node-xml2js icon indicating copy to clipboard operation
node-xml2js copied to clipboard

How to drop array indexes?

Open cyberwombat opened this issue 11 years ago • 19 comments

cyberwombat avatar Jan 06 '14 21:01 cyberwombat

nvrmind...

cyberwombat avatar Jan 06 '14 22:01 cyberwombat

Hey, how do you drop array indexes? I would like to not have them but are unsure how to do so?

mackrauss avatar Feb 18 '14 20:02 mackrauss

Sorry, what do you mean by dropping array indexes? Erm, xml2js arrays are normal JS arrays and support the same operations.

Leonidas-from-XIV avatar Feb 18 '14 20:02 Leonidas-from-XIV

Well if I use

var xml = builder.buildObject(obj);

Where object is a JS array holding JS objects the resulting XML looks something like this:

<root>
  <0>
    <!-- object structure as xml -->
  </0>
  <1>
    <!-- object structure as xml -->
  </1>
</root>

Now I would love to not have the 0, 1, 2 tags since that seems to be invalid XML (at least my browser thinks so). I would either like to not have the 0, 1, .. tags or name them.

Any thoughts?

mackrauss avatar Feb 18 '14 21:02 mackrauss

Well, xml2js should not generate invalid XML, so that's what I would consider a bug…

Leonidas-from-XIV avatar Feb 19 '14 02:02 Leonidas-from-XIV

Here's some data how you can reproduce this problem:

{someArray : [{item:{some:"data"}}, {item:{some:"data"}}]}

converts to:

<someArray>
  <0>
    <item>
      <some>data</some>
    </item>
  </0>
  <1>
    <item>
      <some>data</some>
    </item>
  </1>
</someArray>

but:

{someArray : {item: [{some:"data"}, {some:"data"}]}}

converts to:

<someArray>
  <item>
    <some>data</some>
  </item>
  <item>
    <some>data</some>
  </item>
</someArray>

it seams that it has something to with the array being too close to the root element.

niom avatar Jun 01 '14 21:06 niom

I think I figured this one out and why there are the indexes.

{someArray : [{item:{some:"data"}}, {item:{some:"data"}}]}

someArray is the root object someArray has been stated as array of items in JSON.

this would be converted to xml :

<someArray></someArray>
</someArray></someArray>
...

but the xml does not allow empty root element nor it will not allow multiple elements without a root element. So in this case the json -> xml makes the someArray as the root element and generates indexes under the root element.

<someArray>
<0></0>
<1></1>
...
</someArray>

niom avatar Jun 02 '14 16:06 niom

I recently using NW.js to build up my own desktop app and also came across the same issue. The reason causing this problem might be the condition statement of determine if the variable is an Array:

typeof child === 'object' && child instanceof Array

So, I just replaced the 'instanceof ' with the util module in Node.js:

util.isArray(child);

This seems work. But still, I don't know why instanceof Array doesn't work here. I hope these information would help people who also come across this issue.

Roman-Lo avatar Feb 17 '15 05:02 Roman-Lo

@Roman-Lo I've just tried it and it does not seem to make a difference in my testing.

Leonidas-from-XIV avatar Feb 17 '15 20:02 Leonidas-from-XIV

Hi guys, as a quick solution for a project I'm implementing now, did this (see below). I know it's not the most elegant solution in the world, but my project has been up for while now and no probs at all. Only xml tags with numeric values are removed.

var builder = new xml2js.Builder(options);
var obj = {documents:[{lines:{name: "Super", Surname: "Man", age: 23}},{lines:{name: "Super", Surname: "Man2", age: 24}}]};
var xml = builder.buildObject(obj);
var returnxml = xml.replace(/<\/?[0-9]{1,}>/g,'');

This also work (going down one level when defining the object):

var builder = new xml2js.Builder(options);
var obj = {documents: {document:[{name: "Super", Surname: "Man", age: 23},{name: "Super", Surname: "Man2", age: 24}]}};
var xml = builder.buildObject(obj);

Hope it can help somebody :-)

joaopiopedreira avatar Mar 16 '15 19:03 joaopiopedreira

any fix for this yet?

starter69 avatar Sep 16 '16 15:09 starter69

If I try: builder.buildObject([{"a": 1}, {"b": 2}]) this will result into:

<root>
  <0>
     <a>1</a>
  </0>
  <1>
     <b>2</b>
  </1>
</root>

which is invalid xml. Still no fix?

Daaarkling avatar Feb 02 '17 17:02 Daaarkling

Waiting on a fix too, same problem

jacks50 avatar Feb 21 '17 13:02 jacks50

Thanks for the bug reports on this issue. If someone has the time to find a fix and submit a pull request it would be much appreciated. I contributed the builder code years ago and I haven't had time to work on it.

jacksenechal avatar Feb 21 '17 17:02 jacksenechal

Hi everyone. I can see from today, that this issue has not been fixed. I have created an object like:

{ paragraphs: [{ paragraph: "TextA" }, { paragraph: "TextB" }]}

Returning:

<paragraphs>
  <paragraph>
    TextA
  </paragraph>
</paragraphs>
<paragraphs>
  <paragraph>
    TextB
  </paragraph>
</paragraphs>

Did id do something wrong? Running Version 0.4.19

AndreKirchner avatar May 21 '19 08:05 AndreKirchner

Hi everyone. I can see from today, that this issue has not been fixed. I have created an object like:

{ paragraphs: [{ paragraph: "TextA" }, { paragraph: "TextB" }]}

Returning:

<paragraphs>
  <paragraph>
    TextA
  </paragraph>
</paragraphs>
<paragraphs>
  <paragraph>
    TextB
  </paragraph>
</paragraphs>

Did id do something wrong? Running Version 0.4.19

Hi AndreKirchner,

I don't know it is too late or not, but your json object has a little mistake. Checkout the https://stackoverflow.com/questions/43673396/json-to-xml-with-xml2js-array-elementname. Your json object shoukd be like below { paragraphs: { paragraph: ["TextA", "TextB"] } }

muratonnet avatar Jun 16 '19 13:06 muratonnet

Update to 0.4.22, it's solved in that version

astrocumbia avatar Oct 18 '19 19:10 astrocumbia

I confirm it's working now, you can even use objects inside the array, e.g.: { paragraphs: { paragraph: [{Caption: "TextA"}, {Caption: "TextB"}] } }

sincontri avatar Oct 23 '19 09:10 sincontri