Leonidas-from-XIV / node-xml2js

XML to JavaScript object converter.
MIT License
4.87k stars 601 forks source link

Implicit writing of `<root>` tag is non-intuitive #564

Open jhorbulyk opened 4 years ago

jhorbulyk commented 4 years ago

Consider the following example code:

const xml2js = require('xml2js');
const builder = new xml2js.Builder({
    headless: true,
});
sampleObject = {
    foo: 'bar',
};
console.log(`Sample A: \n${builder.buildObject(sampleObject)}\n`);
sampleObject.bar = 'baz';
console.log(`Sample B: \n${builder.buildObject(sampleObject)}\n`);

This results in the following output:

Sample A: 
<foo>bar</foo>

Sample B: 
<root>
  <foo>bar</foo>
  <bar>baz</bar>
</root>

Observe that when XML is built from an object with a single key, that single key becomes the root of the XML object. However, when XML is built from an object with multiple keys, an implicit <root> tag is added. As far as I can tell, options such as explicitRoot do not alter this behavior.

I find the above behavior problematic as it causes the locations of elements in the resulting XML to shift based on the number of elements in the incoming object. The output is also odd if input is somehing that isn't an object in JSON.

I understand that XML documents must have a single root/global element. Would it perhaps make sense to add some checks to ensure that the input being converted is an object and has ~at most~ exactly one key ~(excluding keys charkey and attrkey)~?

Leonidas-from-XIV commented 4 years ago

In general I agree with you, having things shift is not nice at all. What would you expect to happen in this check if there is more than one key though?

jhorbulyk commented 4 years ago

What would you expect to happen in this check if there is more than one key though?

I would expect an error to be thrown.