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' ] } }
1
  • 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"}] Commented Nov 16, 2019 at 9:54

2 Answers 2

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 }));
});
Sign up to request clarification or add additional context in comments.

1 Comment

please notice that if your xml node name had a "text" attribute it wouldn't be present in the output json
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"
            }
        ]
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.