1

I am trying to convert an XML file into JSON using xml2js on Node.JS.

When I hit an attribute, it will give a '_' and '$' characters as replacement.

I am fully aware that JSON does not have the concept of attributes that XML does.

How do I convert the following XML document:

<id>
  <name language="en">Bob</name>
  <name>Alice</name>
</id>

Into a JSON format something like:

{
    "id": {
        "name": [{
            "language": "en",
            "text": "bob"
        }, "alice"]
    }
}

My code in Node.JS is:

const fs = require('fs');
const util = require('util');
const json = require('json');
const xml2js = require('xml2js');

const xml = fs.readFileSync('./test.xml', 'utf-8', (err, data) => {
  if (err) throw err;  
});

const jsonStr = xml2js.parseString(xml, function (err, result) {
  if (err) throw err;
    console.log(util.inspect(JSON.parse(JSON.stringify(result)), { depth: null }));
});

The current output is:

{ id: { name: [ { _: 'Bob', '$': { language: 'en' } }, 'Alice' ] } }
thotheolh
  • 7,040
  • 7
  • 33
  • 49
  • 1
    I don't think your targeted output is coherent, your second value should be an object two instead of a string, "name": [{ "language": "en", "text": "bob" }, {text: "alice"}] – Jerome Diaz Nov 16 '19 at 09:54

2 Answers2

1

will output

{
  id: { name: [ { language: 'en', text: 'Bob' }, { text: 'Alice' } ] }
}

the code:

const fs = require('fs');
const util = require('util');
const json = require('json');
const xml2js = require('xml2js');

const xml = fs.readFileSync('./test.xml', 'utf-8', (err, data) => {
  if (err) throw err;  
});

const jsonStr = xml2js.parseString(xml, function (err, result) {

  const nameArray = result.id.name;

  const newNameArray = nameArray.map(nameValue => {
    let text = '';
    let attributes = {};
    if (typeof nameValue === 'string') {
      text = nameValue
    } else if (typeof nameValue === 'object') {
      text = nameValue['_']
      attributes = nameValue['$']
    }
    return {
      ...attributes,
      text
    }
  })

  const newResult = {
    id: {
      name: newNameArray
    }
  }

  if (err) throw err;
    console.log(util.inspect(JSON.parse(JSON.stringify(newResult)), { depth: null }));
});
Jerome Diaz
  • 1,746
  • 8
  • 15
1

sth like this

const xml = `
<id>
  <name language="en">Bob</name>
  <name>Alice</name>
</id>`

const { transform } = require('camaro')

const template = {
    id: {
        name: ['id/name', {
            lang: '@language',
            text: '.'
        }]
    }
}

;(async function () {
    console.log(JSON.stringify(await transform(xml, template), null, 4))
})()

output

{
    "id": {
        "name": [
            {
                "lang": "en",  
                "text": "Bob"  
            },
            {
                "lang": "",    
                "text": "Alice"
            }
        ]
    }
}
Tuan Anh Tran
  • 6,807
  • 6
  • 37
  • 54