0

I'm trying to parse a xml to json & i'm using xml2js in nodejs. Below is my code

var chai = require('chai');
var chaiHttp = require('chai-http');
var request = chai.request;
var should = chai.should();
var expect = chai.expect;
var assert = chai.assert;
var supertest = require('supertest');
var fs = require('fs');
var xmlLocation = "./configdata/xmlDoc.xml";

var xml2js = require('xml2js');
var parser = new xml2js.Parser();

//Plugin for HTTP, etc.
chai.use(chaiHttp);
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';

//xmlFile = JSON.parse(fs.readFileSync(xmlData, 'utf8'));


describe("Test : ", function () {

    it("convert xml to json", function (done) {

        r = fs.readFileSync(xmlLocation, 'UTF-8');
        parser.parseString(r, function (err, parsedData) {
            if (err) throw err;
            else {
                fs.writeFile("jsonData.json", JSON.stringify(parsedData), function (err, response) {
                });
            }
        });

        done();
    });

})

My sample xml file :

<?xml version="1.0" encoding="UTF-8" ?>
<ALEXA>
    <SD TITLE="A" FLAGS="" HOST="davidwalsh.name">
        <TITLE TEXT="David Walsh Blog :: PHP, MySQL, CSS, Javascript, MooTools, and Everything Else"/>
        <LINKSIN NUM="1102"/>
        <SPEED TEXT="1421" PCT="51"/>
    </SD>
    <SD>
        <POPULARITY URL="davidwalsh.name/" TEXT="7131"/>
        <REACH RANK="5952"/>
        <RANK DELTA="-1648"/>
    </SD>
</ALEXA>

I'm getting the below output :

{
  "ALEXA": {
    "SD": [
      {
        "$": {
          "TITLE": "A",
          "FLAGS": "",
          "HOST": "davidwalsh.name"
        },
        "TITLE": [
          {
            "$": {
              "TEXT": "David Walsh Blog :: PHP, MySQL, CSS, Javascript, MooTools, and Everything Else"
            }
          }
        ],
        "LINKSIN": [
          {
            "$": {
              "NUM": "1102"
            }
          }
        ],
        "SPEED": [
          {
            "$": {
              "TEXT": "1421",
              "PCT": "51"
            }
          }
        ]
      },
      {
        "POPULARITY": [
          {
            "$": {
              "URL": "davidwalsh.name/",
              "TEXT": "7131"
            }
          }
        ],
        "REACH": [
          {
            "$": {
              "RANK": "5952"
            }
          }
        ],
        "RANK": [
          {
            "$": {
              "DELTA": "-1648"
            }
          }
        ]
      }
    ]
  }
}

'$' is getting added to the parsed json. How to avoid it..??

Looking for a solution. Thanks in advance.

3 Answers3

0

The $ is the place for your attributes with the default config.

As xml2js parses your XML tags (SD for example) explicitly as arrays (with explicitArray=true - you either way have multiple of them, and you can only assign one similar key per object in JSON), you need a place to store the attributes, this is what $ is for. You can enforce creating arrays using (which is the default) or turn this off. Using mergeAttrs you might eventually get a result, that you desire.

You can change the attrkey if that would be one solution as well. The same goes for charkey and so on. You can find the whole config options in the README on GitHub at https://github.com/Leonidas-from-XIV/node-xml2js - eventually an option to transform to children might the right for you.

If you don't need attributes at all you can set ignoreAttrs=true. By the way; parser options go as an object into the parser constructor, in your case: new xml2js.Parser({...options});

Severin
  • 308
  • 1
  • 11
  • yeah, actually i'm very new to this platform, so any sample code snippet will make my life easy. – Sandeep Teja Mummoji May 23 '17 at 03:47
  • Of course :-) You have var parser = new xml2js.Parser(); in your code, which creates your parser instance. In the constructor of Parser you can pass an options object like so var parser = new xml2js.Parser({optionName: optionValue}); The options available are on the GitHub README I posted. So to parse the XML according to your needs I would play a bit with the options. But the relevant would probably be var parser = new xml2js.Parser({mergeAttrs: true, attrkey: 'ANYTHINGELSE' }); - Could you add, how you want to parse your XML to JSON (how it should "look like")? – Severin May 23 '17 at 06:38
0

library like this usually parse everything and sometimes resulting in having many properties which you don't need.

i created camaro for this purpose.

downside of this is you have to write your own template file for the structure you want xml to be transform to.

const transform = require('camaro')
const fs = require('fs')

const xml = fs.readFileSync('ean.xml', 'utf-8')
const template = {
    cache_key: "/HotelListResponse/cacheKey",
    hotels: ["//HotelSummary", {
        hotel_id: "hotelId",
        name: "name",
        rooms: ["RoomRateDetailsList/RoomRateDetails", {
            rates: ["RateInfos/RateInfo", {
                currency: "ChargeableRateInfo/@currencyCode",
                non_refundable: "nonRefundable",
                price: "ChargeableRateInfo/@total"
            }],
            room_name: "roomDescription",
            room_type_id: "roomTypeCode"
        }]
    }],
    session_id: "/HotelListResponse/customerSessionId"
}

const result = transform(xml, template)
Tuan Anh Tran
  • 6,807
  • 6
  • 37
  • 54
0

Instead xml2js, use xml2json which converts exactly from xml to json with the specific keys.

Kalpana Raman
  • 51
  • 2
  • 5