2017-05-22 105 views
0

我想解析一个xml到json &我在nodejs中使用了xml2js。 下面是我的代码无法正确解析xml到json

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(); 
    }); 

}) 

我的示例XML文件:

<?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> 

,我发现了以下的输出:

{ 
    "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" 
      } 
      } 
     ] 
     } 
    ] 
    } 
} 

'$' 是被添加到该解析JSON。如何避免它.. ??

寻找解决方案。提前致谢。

回答

0

$是您的属性与默认配置的地方。

由于xml2js以数组的形式显式地解析XML标记(例如SD)(显式数组= = true - 无论哪种方式都有多个,并且每个对象只能在JSON中分配一个相似的键)存储这些属性,这是$的目的。您可以使用(这是默认设置)强制创建阵列或关闭此功能。使用mergeAttrs你可能最终会得到一个你期望的结果。

如果这也是一种解决方案,您可以更改attrkey。这同样适用于charkey等。您可以在GitHub上的README中找到整个配置选项https://github.com/Leonidas-from-XIV/node-xml2js - 最终,转换为子项的选项可能适合您。

如果你根本不需要属性,你可以设置ignoreAttrs = true。顺便一提;解析器选项将作为对象放入解析器构造函数中,如下所示:new xml2js.Parser({... options});

+0

是的,其实我对这个平台很新,所以任何示例代码片段都会让我的生活变得轻松。 –

+0

当然:-) 你有var parser = new xml2js.Parser();在您的代码中创建您的解析器实例。在Parser的构造函数中,您可以传递一个选项对象,如下所示:var parser = new xml2js.Parser({optionName:optionValue}); 可用选项位于我发布的GitHub自述文件中。所以为了根据你的需求解析XML,我会玩一些选项。但相关可能会是var parser = new xml2js.Parser({mergeAttrs:true,attrkey:'ANYTHINGELSE'}); - 你可以添加,你想如何解析你的XML到JSON(它应该“看起来像”)? – Severin

0

像这样的库通常解析所有内容,有时会导致拥有许多您不需要的属性。为此,我创建了camaro

这个缺点是你必须编写自己的模板文件,用于你想要将xml转换成的结构。

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)