Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversion from XML to JSON array inconsistency #30

Closed
eugenevd opened this issue Jul 9, 2020 · 7 comments
Closed

Conversion from XML to JSON array inconsistency #30

eugenevd opened this issue Jul 9, 2020 · 7 comments
Assignees
Labels
bug Something isn't working

Comments

@eugenevd
Copy link

eugenevd commented Jul 9, 2020

Describe the bug
Given XML with multiple rows:

    <data>
        <row id="0">
            <TYPE>X</TYPE>
            <ID>123</ID>            
        </row>
        <row id="1">
            <TYPE>Y</TYPE>
            <ID>321</ID>           
        </row>
    </data>   

produces JSON with row as array.

vs XML with a single row:

    <data>
        <row id="0">
            <TYPE>X</TYPE>
            <ID>123</ID>            
        </row>
    </data>   

produced JSON with row not as an array.

To Reproduce

const expect = chai.expect;
const { convert } = require('xmlbuilder2');
describe('Test XML to JSON arrays', function ()
{
    it('Multiple items in XML should result in JSON array', async function()
    {
        const XMLmulti = '<export><data><row id="0"><TYPE>X</TYPE><ID>123</ID></row><row id="1"><TYPE>Y</TYPE><ID>321</ID></row></data></export>';
        let JSONmulti = convert(XMLmulti, { format: "object" });
        expect(JSONmulti.export.data.row.length).to.equal(2);
    });
    it('Single item in XML should result in JSON array', async function()
    {
        const XMLsingle = '<export><data><row id="0"><TYPE>X</TYPE><ID>123</ID></row></data></export>';
        let JSONsingle = convert(XMLsingle, { format: "object" });
        expect(JSONsingle.export.data.row.length).to.equal(1);
    });
});

Expected behavior
Result:
{ "export": { "data": { "row": { "@id": "0", "TYPE": "X", "ID": "123" } } } }
Expected:
{ "export": { "data": { "row": [{ "@id": "0", "TYPE": "X", "ID": "123" }] } } }

Version:

  • node.js: [12.18.0]
  • xmlbuilder2 [2.1.6]
@eugenevd eugenevd added the bug Something isn't working label Jul 9, 2020
@oozcitak
Copy link
Owner

oozcitak commented Jul 9, 2020

This would force elements with single child nodes to always create arrays. I don't think we want this:

{
  root: [
    {
      child: [
        {
          grandchild: [
            {
              "text"
            }
          ]
        }
      ]
    }
  ]
}

Your expected output should also be:

Expected:
{ "export": [{ "data": [{ "row": [{ "@id": "0", "TYPE": "X", "ID": "123" }] }] }] }

as "row", "data" and "export" are all elements with single child nodes.

Is there a reason you want this feature, or is it just for consistency's sake?

@IamRaduB
Copy link

IamRaduB commented Jul 9, 2020

Encountering the same issue. It would be great to be able to pass a set of xpaths to the converter telling it: these nodes should be arrays.

@oozcitak
Copy link
Owner

oozcitak commented Jul 9, 2020

pass a set of xpaths to the converter

@IamRaduB If I am understanding this correctly, you want to be able to determine which element nodes should have their contents to be always grouped into an array. I am guessing you are post-processing the resulting JS object. Maybe it would be better to allow customizing the converter; so you can tweak the output as you require. Can you describe the use case a bit?

@gpyshenko
Copy link

I support this proposal, it very useful. It is convenient to get the expected result.

@eugenevd
Copy link
Author

For me it's about consistency. I retrieve XML data from a SOAP service. After converting to JSON, I process it. The code would be much simpler if I knew I'll always have an array where expected (array with 0,1 or more elements).

@leog
Copy link

leog commented Aug 5, 2020

I too bumped with this requirement @oozcitak. Maybe using the element custom parser to enforce array treatment for selected element names? 🤔

Otherwise in order to let the dev choose, the verbose option could be a boolean or a list of keys to check whether the array treatment should apply or not 🤩

@oozcitak
Copy link
Owner

oozcitak commented Aug 5, 2020

@leog I started working on custom serializers. You can track of the progress at #47

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants