Open gabmontes opened 10 years ago
No, I think it is just an artifact of the implementation, which doesn't check for undefined. In any case, it is kinda unclear what the XML representation of undefined
would even be. "undefined"? That would get read as "undefined" and so the translation is not really transparent (a property that I think is kinda neat).
@Leonidas-from-XIV thanks for your quick reply!
Any alternative chosen should let us go JSON > XML > JSON and get an equivalent object in the end. Much the same as JSON.parse and JSON.stringify. Then, a property set to undefined
should not be translated to the XML. What do you think?
IMHO, what should not happen is the library to fail if a valid JSON is given to the XML builder, no matter what the final decision is in regards to the values that do not translate well to an XML as undefined
or perhaps null
.
Yes, I think it would be better to bail on invalid input instead of generating XML that might be ok, but is mysteriously missing some items, because they were accidentally set to undefined or something.
To some extent, this has been fixed, but some issues remain.
const xml2js = require('xml2js');
function test(js) {
let builder = new xml2js.Builder({
headless: true
});
console.dir(js, {depth: null});
try {
let xml = builder.buildObject(js);
console.log(xml);
}
catch (err) {
console.log(err.stack.split('\n', 5).join('\n')+'\n ...');
}
console.log();
}
test({root: ''});
test({root: null});
test({root: undefined});
test({name: "Super", age: ''});
test({name: "Super", age: null});
test({name: "Super", age: undefined});
test({name: "Super", age: ['']});
test({name: "Super", age: [null]});
test({name: "Super", age: [undefined]});
test({root: {name: "Super", age: ''}});
test({root: {name: "Super", age: null}});
test({root: {name: "Super", age: undefined}});
test({root: {name: "Super", age: ['']}});
test({root: {name: "Super", age: [null]}});
test({root: {name: "Super", age: [undefined]}});
test({root: {$: {foo: ''}}});
test({root: {$: {foo: null}}});
test({root: {$: {foo: undefined}}});
test({root: {child: {$: {foo: ''}}}});
test({root: {child: {$: {foo: null}}}});
test({root: {child: {$: {foo: undefined}}}});
Output (paths in stack traces sanitized):
{ root: '' }
<root/>
{ root: null }
<root/>
{ root: undefined }
Error: Missing element text
at new XMLText (./node_modules/xmlbuilder/lib/XMLText.js:15:15)
at XMLElement.module.exports.XMLNode.text (./node_modules/xmlbuilder/lib/XMLNode.js:165:15)
at XMLElement.module.exports.XMLNode.txt (./node_modules/xmlbuilder/lib/XMLNode.js:365:19)
at ./node_modules/xml2js/lib/builder.js:57:23
...
{ name: 'Super', age: '' }
<root>
<name>Super</name>
<age/>
</root>
{ name: 'Super', age: null }
<root>
<name>Super</name>
<age/>
</root>
{ name: 'Super', age: undefined }
<root>
<name>Super</name>
<age/>
</root>
{ name: 'Super', age: [ '' ] }
<root>
<name>Super</name>
<age/>
</root>
{ name: 'Super', age: [ null ] }
<root>
<name>Super</name>
<age/>
</root>
{ name: 'Super', age: [ undefined ] }
Error: Missing element text
at new XMLText (./node_modules/xmlbuilder/lib/XMLText.js:15:15)
at XMLElement.module.exports.XMLNode.text (./node_modules/xmlbuilder/lib/XMLNode.js:165:15)
at XMLElement.module.exports.XMLNode.txt (./node_modules/xmlbuilder/lib/XMLNode.js:365:19)
at ./node_modules/xml2js/lib/builder.js:57:23
...
{ root: { name: 'Super', age: '' } }
<root>
<name>Super</name>
<age/>
</root>
{ root: { name: 'Super', age: null } }
<root>
<name>Super</name>
<age/>
</root>
{ root: { name: 'Super', age: undefined } }
<root>
<name>Super</name>
<age/>
</root>
{ root: { name: 'Super', age: [ '' ] } }
<root>
<name>Super</name>
<age/>
</root>
{ root: { name: 'Super', age: [ null ] } }
<root>
<name>Super</name>
<age/>
</root>
{ root: { name: 'Super', age: [ undefined ] } }
Error: Missing element text
at new XMLText (./node_modules/xmlbuilder/lib/XMLText.js:15:15)
at XMLElement.module.exports.XMLNode.text (./node_modules/xmlbuilder/lib/XMLNode.js:165:15)
at XMLElement.module.exports.XMLNode.txt (./node_modules/xmlbuilder/lib/XMLNode.js:365:19)
at ./node_modules/xml2js/lib/builder.js:57:23
...
{ root: { '$': { foo: '' } } }
<root foo=""/>
{ root: { '$': { foo: null } } }
Error: Missing attribute value for attribute foo of element root
at new XMLAttribute (./node_modules/xmlbuilder/lib/XMLAttribute.js:13:15)
at XMLElement.module.exports.XMLElement.attribute (./node_modules/xmlbuilder/lib/XMLElement.js:72:35)
at XMLElement.module.exports.XMLElement.att (./node_modules/xmlbuilder/lib/XMLElement.js:100:19)
at ./node_modules/xml2js/lib/builder.js:76:39
...
{ root: { '$': { foo: undefined } } }
Error: Missing attribute value for attribute foo of element root
at new XMLAttribute (./node_modules/xmlbuilder/lib/XMLAttribute.js:13:15)
at XMLElement.module.exports.XMLElement.attribute (./node_modules/xmlbuilder/lib/XMLElement.js:72:35)
at XMLElement.module.exports.XMLElement.att (./node_modules/xmlbuilder/lib/XMLElement.js:100:19)
at ./node_modules/xml2js/lib/builder.js:76:39
...
{ root: { child: { '$': { foo: '' } } } }
<root>
<child foo=""/>
</root>
{ root: { child: { '$': { foo: null } } } }
Error: Missing attribute value for attribute foo of element child
at new XMLAttribute (./node_modules/xmlbuilder/lib/XMLAttribute.js:13:15)
at XMLElement.module.exports.XMLElement.attribute (./node_modules/xmlbuilder/lib/XMLElement.js:72:35)
at XMLElement.module.exports.XMLElement.att (./node_modules/xmlbuilder/lib/XMLElement.js:100:19)
at ./node_modules/xml2js/lib/builder.js:76:39
...
{ root: { child: { '$': { foo: undefined } } } }
Error: Missing attribute value for attribute foo of element child
at new XMLAttribute (./node_modules/xmlbuilder/lib/XMLAttribute.js:13:15)
at XMLElement.module.exports.XMLElement.attribute (./node_modules/xmlbuilder/lib/XMLElement.js:72:35)
at XMLElement.module.exports.XMLElement.att (./node_modules/xmlbuilder/lib/XMLElement.js:100:19)
at ./node_modules/xml2js/lib/builder.js:76:39
...
@Leonidas-from-XIV if you try to build an XML out of an object containing
undefined
properties, the program crashes.For instance, the following code will fail:
On the other hand, if the
age
property isnull
, the builder works fine.Is there a rationale behind the difference?