简体   繁体   中英

Convert XML to JSON with NodeJS

I'm trying to convert the following xml to json, thereby I need to get a mapping to the TS-tc-dt

Here is the xml

<?xml version="1.0" encoding="UTF-8"?>
<TestScenario>
   <TestSuite name="TS_EdgeHome">
      <TestCaseName name="tc_Login">dt_EdgeCaseHome,dt_EdgeCaseRoute</TestCaseName>
      <TestCaseName name="tc_Logout">dt_EdgeCaseRoute</TestCaseName>
   </TestSuite>
   <TestSuite name="TS_EdgePanel">
      <TestCaseName name="tc_AddContract">dt_EdgeCaseHome,dt_EdgeCaseSpectrum</TestCaseName>
   </TestSuite>
      <TestSuite name="TS_EdgeRoute">
      <TestCaseName name="tc_VerifyContract">dt_EdgeCaseRoute</TestCaseName>
      <TestCaseName name="tc_Payment">dt_EdgeCaseRoute</TestCaseName>
   </TestSuite>
   <TestSuite name="TS_EdgeSpectrum">
      <TestCaseName name="tc_ClientFeedback">dt_EdgeCaseSpectrum</TestCaseName>
   </TestSuite>
</TestScenario>

How can I achieve this in NodeJS?

I've used xml-js - npm to get the desired result.

First of all I've installed xml-js via npm install xml-js

Then used the below code to get the output in json format

var convert = require('xml-js');
var xml = require('fs').readFileSync('./testscenario.xml', 'utf8');

var result = convert.xml2json(xml, {compact: true, spaces: 4});
console.log(result);

You can use xml2json npm for converting your xml in to json. xml2json .

Step 1:- Install package in you project

npm install xml2json

Step 2:- You can use that package and convert your xml to json

let xmlParser = require('xml2json');
let xmlString = `<?xml version="1.0" encoding="UTF-8"?>
<TestScenario>
   <TestSuite name="TS_EdgeHome">
      <TestCaseName name="tc_Login">dt_EdgeCaseHome,dt_EdgeCaseRoute</TestCaseName>
      <TestCaseName name="tc_Logout">dt_EdgeCaseRoute</TestCaseName>
   </TestSuite>
   <TestSuite name="TS_EdgePanel">
      <TestCaseName name="tc_AddContract">dt_EdgeCaseHome,dt_EdgeCaseSpectrum</TestCaseName>
   </TestSuite>
      <TestSuite name="TS_EdgeRoute">
      <TestCaseName name="tc_VerifyContract">dt_EdgeCaseRoute</TestCaseName>
      <TestCaseName name="tc_Payment">dt_EdgeCaseRoute</TestCaseName>
   </TestSuite>
   <TestSuite name="TS_EdgeSpectrum">
      <TestCaseName name="tc_ClientFeedback">dt_EdgeCaseSpectrum</TestCaseName>
   </TestSuite>
</TestScenario>`;

console.log('JSON output', xmlParser.toJson(xmlString));

Hope this might be helps to you.

If you are choosing between xml2json and xml-js then as far as I understand the differences are:

  • xml-js has much less dependencies and uses sax-js for xml parsing.
  • xml2json has more dependencies including node-expat that requires python and can be a headache during npm i. But node-expat claims to be ~3 times faster than sax-js.

Also be aware that xml2json and xml-js produce a bit different JSON. When I replaced xml2json with xml-js I had to add "._attributes" everywhere where values were in attributes.

In 6 simple ES6 lines:

xml2json = xml => {                                                                                                                                                     
  var el = xml.nodeType === 9 ? xml.documentElement : xml                                                                                                               
  var h  = {name: el.nodeName}                                                                                                                                          
  h.content    = Array.from(el.childNodes || []).filter(e => e.nodeType === 3).map(e => e.textContent).join('').trim()                                                  
  h.attributes = Array.from(el.attributes || []).filter(a => a).reduce((h, a) => { h[a.name] = a.value; return h }, {})                                                 
  h.children   = Array.from(el.childNodes || []).filter(e => e.nodeType === 1).map(c => h[c.nodeName] = xml2json(c))                                                    
  return h                                                                                                                                                              
}

Test with echo "xml2json_example()" | node -r xml2json.es6 echo "xml2json_example()" | node -r xml2json.es6 with source at https://github.com/brauliobo/biochemical-db/blob/master/lib/xml2json.es6

Cruftless allows you to 'annotate' the data structure you want to match, to specify how it should be bound to a JSON representation of that same data.

So, if you define your template like this:

<TestScenario>
  <TestSuite name="{{name}}"><?bind suites|array?>
    <TestCaseName name="{{name}}">{{data}}</TestCaseName><?bind cases|array?>
  </TestSuite>
</TestScenario>

Then by calling .fromXML on the object created from it, passing in the XML you want to parse, you will get:

{
  suites: [
    { name: 'tc_Logout', data: 'dt_EdgeCaseRoute' },
    {
      name: 'tc_AddContract',
      data: 'dt_EdgeCaseHome,dt_EdgeCaseSpectrum'
    },
    { name: 'tc_Payment', data: 'dt_EdgeCaseRoute' },
    { name: 'tc_ClientFeedback', data: 'dt_EdgeCaseSpectrum' }
  ]
}

You can also try camaro

const { transform } = require('camaro')

const xml = `
<?xml version="1.0" encoding="UTF-8"?>
<TestScenario>
   <TestSuite name="TS_EdgeHome">
      <TestCaseName name="tc_Login">dt_EdgeCaseHome,dt_EdgeCaseRoute</TestCaseName>
      <TestCaseName name="tc_Logout">dt_EdgeCaseRoute</TestCaseName>
   </TestSuite>
   <TestSuite name="TS_EdgePanel">
      <TestCaseName name="tc_AddContract">dt_EdgeCaseHome,dt_EdgeCaseSpectrum</TestCaseName>
   </TestSuite>
      <TestSuite name="TS_EdgeRoute">
      <TestCaseName name="tc_VerifyContract">dt_EdgeCaseRoute</TestCaseName>
      <TestCaseName name="tc_Payment">dt_EdgeCaseRoute</TestCaseName>
   </TestSuite>
   <TestSuite name="TS_EdgeSpectrum">
      <TestCaseName name="tc_ClientFeedback">dt_EdgeCaseSpectrum</TestCaseName>
   </TestSuite>
</TestScenario>
`

;(async function () {
    const result = await transform(xml, {
        testSuites: [
            '/TestScenario/TestSuite',
            {
                name: '@name',
                testCases: ['TestCaseName', {
                    name: '@name',
                    data: '.'
                }]
            }
        ]
    })

    console.log(JSON.stringify(result, null, 2))
})()

output:

{
  "testSuites": [
    {
      "name": "TS_EdgeHome",
      "testCases": [
        {
          "name": "tc_Login",
          "data": "dt_EdgeCaseHome,dt_EdgeCaseRoute"
        },
        {
          "name": "tc_Logout",
          "data": "dt_EdgeCaseRoute"
        }
      ]
    },
    {
      "name": "TS_EdgePanel",
      "testCases": [
        {
          "name": "tc_AddContract",
          "data": "dt_EdgeCaseHome,dt_EdgeCaseSpectrum"
        }
      ]
    },
    {
      "name": "TS_EdgeRoute",
      "testCases": [
        {
          "name": "tc_VerifyContract",
          "data": "dt_EdgeCaseRoute"
        },
        {
          "name": "tc_Payment",
          "data": "dt_EdgeCaseRoute"
        }
      ]
    },
    {
      "name": "TS_EdgeSpectrum",
      "testCases": [
        {
          "name": "tc_ClientFeedback",
          "data": "dt_EdgeCaseSpectrum"
        }
      ]
    }
  ]
}

if you have a XML file, then you can read that XML file using fs in nodejs and then you can use "xml2json" npm package.

    const parser = require('xml2json');
    const fs = require("fs")



    fs.readFile(uploadedFilePath, function(err,data){

        if(err) {
            return res.send({message:err});
        } else {

            jsonfile = JSON.parse(parser.toJson(data,{reversible: true}));

        }

    });

 var fs = require('fs'); var xml2json = require('xml2js'); var parser = new xml2json.Parser(); var i = 0; fs.readFile('note.xml', function(err,data){ parser.parseString(data, function(err, result){ console.log(result); }); });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM