Skip to content

Commit

Permalink
Remove inheritNS option, namespaces are inherited automatically
Browse files Browse the repository at this point in the history
  • Loading branch information
oozcitak committed Mar 29, 2020
1 parent 0b35d07 commit ed3014e
Show file tree
Hide file tree
Showing 11 changed files with 23 additions and 109 deletions.
1 change: 0 additions & 1 deletion docs/pages/builder-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -387,4 +387,3 @@ ___
* `ele` - default namespace for element nodes
* `att` - default namespace for attributes
* `namespaceAlias` - contains namespace aliases where object keys are namespace aliases and object values are namespaces (see: [example]({{ site.baseurl }}{% link pages/namespaces.md %}#namespace-aliases))
* `inheritNS` - whether child element nodes inherit their parent element's namespace. Defaults to `false`. (see: [example]({{ site.baseurl }}{% link pages/namespaces.md %}#namespace-inheritance))
32 changes: 4 additions & 28 deletions docs/pages/namespaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,38 +156,14 @@ console.log(ele.toString()); // '<xml:root xml:att='val'/>'

### Namespace Inheritance

Child element nodes can be made to inherit their parent element's namespace with the `inheritNS` option. For example:
Child element nodes automatically inherit their parent element's namespace. For example:
```js
const { create } = require('xmlbuilder2');

const ele = create({ inheritNS: true })
const root = create()
.ele('http:/example.com', 'root')
.ele('node')
.up();
console.log(ele.toString()); // '<root xmlns='http:/example.com'><node/></root>'
```

Consider the same example without the `inheritNS` option:
```js
const { create } = require('xmlbuilder2');

const ele = create()
.ele('http:/example.com', 'root')
.ele('node')
.up();
console.log(ele.toString()); // '<root xmlns='http:/example.com'><node xmlns=''/></root>'
```

`inheritNS` can be changed on the fly:
```js
const { create } = require('xmlbuilder2');

const ele = create()
.ele('http:/example.com', 'root')
.set({ inheritNS: true })
.ele('node').up()
.set({ inheritNS: false })
.ele('node').up()
.up();
console.log(ele.toString()); // '<root xmlns='http:/example.com'><node/><node xmlns=''/></root>'
const node = root.node.firstElementChild;
console.log(node.namespaceURI); // 'http:/example.com'
```
21 changes: 0 additions & 21 deletions docs/pages/other-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,6 @@ for the options argument.
<br/>

* `options` - builder options

The following example sets the `inheritNS` option to `true` while creating the first `node` element then changes back to `false` while creating the second `node` element.

```js
const { create } = require('xmlbuilder2');

const ele = create()
.ele('http:/example.com', 'root')
.set({ inheritNS: true })
.ele('node').up()
.set({ inheritNS: false })
.ele('node').up()
.up();
console.log(ele.end({ prettyPrint: true }));
```
```xml
<root xmlns="http:/example.com">
<node/>
<node xmlns=""/>
</root>
```
</details>


Expand Down
4 changes: 2 additions & 2 deletions src/builder/XMLBuilderImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,13 @@ export class XMLBuilderImpl implements XMLBuilder {
[namespace, name] = this._extractNamespace(namespace, name, true)

// inherit namespace from parent
if (namespace === undefined && this._options.inheritNS) {
if (namespace === undefined) {
const [prefix] = namespace_extractQName(name)
namespace = this.node.lookupNamespaceURI(prefix)
}

// create a child element node
const childNode = (namespace !== undefined ?
const childNode = (namespace !== undefined && namespace !== null?
this._doc.createElementNS(namespace, name) :
this._doc.createElement(name)
)
Expand Down
16 changes: 8 additions & 8 deletions src/callback/XMLBuilderCBImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ export class XMLBuilderCBImpl extends EventEmitter implements XMLBuilderCB {
this._writer = this._options.format === "xml" ? new XMLCBWriter(this._options) : new JSONCBWriter(this._options)

// automatically create listeners for callbacks passed via options
if (this._options.data !== undefined ){
if (this._options.data !== undefined) {
this.on("data", this._options.data)
}
if (this._options.end !== undefined ){
if (this._options.end !== undefined) {
this.on("end", this._options.end)
}
if (this._options.error !== undefined ){
if (this._options.error !== undefined) {
this.on("error", this._options.error)
}

Expand Down Expand Up @@ -381,7 +381,7 @@ export class XMLBuilderCBImpl extends EventEmitter implements XMLBuilderCB {
}

this._writer.beginElement(qualifiedName)
this._push(this._writer.openTagBegin(qualifiedName))
this._push(this._writer.openTagBegin(qualifiedName))
} else {
let prefix = node.prefix
let candidatePrefix = map.get(prefix, ns)
Expand Down Expand Up @@ -575,8 +575,8 @@ export class XMLBuilderCBImpl extends EventEmitter implements XMLBuilderCB {

for (const attr of node.attributes) {
// Optimize common case
if (!requireWellFormed && attr.namespaceURI === null) {
this._push(this._writer.attribute(attr.localName,
if (!requireWellFormed && !ignoreNamespaceDefinitionAttribute && attr.namespaceURI === null) {
this._push(this._writer.attribute(attr.localName,
this._serializeAttributeValue(attr.value, this._options.wellFormed)))
continue
}
Expand Down Expand Up @@ -633,7 +633,7 @@ export class XMLBuilderCBImpl extends EventEmitter implements XMLBuilderCB {
candidatePrefix = this._generatePrefix(attributeNamespace, map, prefixIndex)
}

this._push(this._writer.attribute("xmlns:" + candidatePrefix,
this._push(this._writer.attribute("xmlns:" + candidatePrefix,
this._serializeAttributeValue(attributeNamespace, this._options.wellFormed)))
}
}
Expand All @@ -646,7 +646,7 @@ export class XMLBuilderCBImpl extends EventEmitter implements XMLBuilderCB {
}

this._push(this._writer.attribute(
(candidatePrefix !== null ? candidatePrefix + ":" : "") + attr.localName,
(candidatePrefix !== null ? candidatePrefix + ":" : "") + attr.localName,
this._serializeAttributeValue(attr.value, this._options.wellFormed)))
}
}
Expand Down
8 changes: 1 addition & 7 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,6 @@ export interface XMLBuilderOptions {
*/
[key: string]: string | null
}
/**
* Whether child element nodes will inherit their parent element's namespace.
* Defaults to `false`.
*/
inheritNS: boolean
}

/**
Expand Down Expand Up @@ -120,8 +115,7 @@ export const DefaultBuilderOptions: XMLBuilderOptions = {
mathml: "http://www.w3.org/1998/Math/MathML",
svg: "http://www.w3.org/2000/svg",
xlink: "http://www.w3.org/1999/xlink"
},
inheritNS: false
}
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/writers/BaseWriter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ export abstract class BaseWriter<T extends BaseWriterOptions, U extends XMLSeria
(localDefaultNamespace !== null && localDefaultNamespace !== ns)) {
/**
* _Note:_ At this point, the namespace for this node still needs to be
* serialized, but there's no prefix (or candidate prefix) availble; the
* serialized, but there's no prefix (or candidate prefix) available; the
* following uses the default namespace declaration to define the
* namespace--optionally replacing an existing default declaration
* if present.
Expand Down Expand Up @@ -1138,7 +1138,7 @@ export abstract class BaseWriter<T extends BaseWriterOptions, U extends XMLSeria
*/
for (const attr of node.attributes) {
// Optimize common case
if (!requireWellFormed && attr.namespaceURI === null) {
if (!requireWellFormed && !ignoreNamespaceDefinitionAttribute && attr.namespaceURI === null) {
result.push([null, null, attr.localName,
this._serializeAttributeValue(attr.value, requireWellFormed)])
continue
Expand Down
34 changes: 0 additions & 34 deletions test/basic/withOptions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,38 +24,4 @@ describe('withOptions()', () => {
expect(() => $$.create({ convert: { comment: "" } })).toThrow()
})

test('with inheritNS', () => {
const doc = $$.create({ inheritNS: true })
.ele("http://example.com", "parent")
.ele("child").doc()

expect(doc.end({ headless: true })).toBe($$.t`
<parent xmlns="http://example.com"><child/></parent>
`)
})

test('without inheritNS', () => {
const doc = $$.create({ inheritNS: false })
.ele("http://example.com", "parent")
.ele("child").doc()

expect(doc.end({ headless: true })).toBe($$.t`
<parent xmlns="http://example.com"><child xmlns=""/></parent>
`)
})

test('change inheritNS with set ', () => {
const doc = $$.create()
.ele("http://example.com", "parent")
.set({ inheritNS: true })
.ele("child").up()
.set({ inheritNS: false })
.ele("child").up().
doc()

expect(doc.end({ headless: true })).toBe($$.t`
<parent xmlns="http://example.com"><child/><child xmlns=""/></parent>
`)
})

})
2 changes: 1 addition & 1 deletion test/issues/issue-006.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ describe('Replicate issue', () => {

// https://github.com/oozcitak/xmlbuilder2/issues/6
test('#6 - When using namespace, empty XMLNs shows up in various child node elements', () => {
const doc = $$.create({ inheritNS: true })
const doc = $$.create()
.ele("http://example.com", "parent")
.ele("child").doc()

Expand Down
6 changes: 3 additions & 3 deletions test/wiki/namespace.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ describe('namespaces examples in the wiki', () => {
const doc = $$.create().ele(ns1, 'root')
.ele('foo').txt('bar').doc()

expect(doc.end({ headless: true })).toBe('<root xmlns="http://example.com/ns1"><foo xmlns="">bar</foo></root>')
expect(doc.end({ headless: true })).toBe('<root xmlns="http://example.com/ns1"><foo>bar</foo></root>')
})

test('reset default namespace', () => {
Expand All @@ -25,7 +25,7 @@ describe('namespaces examples in the wiki', () => {
const doc = $$.create().ele(ns1, 'root', {
"xmlns:xsi": xsi,
"xsi:schemaLocation": "http://example.com/n1 schema.xsd" })
.ele('foo').txt('bar').doc()
.ele('', 'foo').txt('bar').doc()

expect(doc.end({ headless: true })).toBe(
'<root xmlns="http://example.com/ns1"' +
Expand All @@ -41,7 +41,7 @@ describe('namespaces examples in the wiki', () => {

const doc = $$.create().ele(svgNs, 'svg', {
"xmlns:xlink": xlinkNs })
.ele('script', { type: "text/ecmascript", "xlink:href": "foo.js" })
.ele('script', { xmlns: "", type: "text/ecmascript", "xlink:href": "foo.js" })
.doc()

expect(doc.end({ headless: true })).toBe(
Expand Down
4 changes: 2 additions & 2 deletions test/writers/XMLWriterNS.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ describe('XMLWriter with namespaces', () => {
.doc()
expect(doc.end({ prettyPrint: true, headless: true })).toBe($$.t`
<xml:root>
<foo/>
<bar/>
<xml:foo/>
<xml:bar/>
</xml:root>
`)
})
Expand Down

0 comments on commit ed3014e

Please sign in to comment.