3

我是新手node.js,需要解析XML. 在 js 中,我只是使用 aDOMParser和 usegetElementsByTagName来获取我想要的值。我刚刚切换到节点并正在使用xml2js(愿意考虑替代方案)。我一直无法弄清楚如何解析响应以获得我正在寻找的东西。

下面的代码:

function parseBody(body){
    var parseString = require('xml2js').parseString;
    var xml = body
    parseString(xml, function (err, result) {
    console.dir(result);
});

这是我传递给函数的 XML:

<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:int=\"realURLHere">
   <soapenv:Header/>
   <soapenv:Body>
      <int:readResponse>
         <response>
            <request>?</request>
            <cust>
               <fName>?</fName>
            </cust>
        </response>
      </int:readResponse>
   </soapenv:Body>
</soapenv:Envelope>

这是我的函数的输出:

{ 'soapenv:Envelope':
   { '$':
      { 'xmlns:soapenv': 'http://schemas.xmlsoap.org/soap/envelope/',
        'xmlns:int': 'realURLHere' },
     'soapenv:Body': [ [Object] ] 
   } 
}

我正在尝试访问 inside 的值,<fName><cust>没有运气。任何帮助,将不胜感激。谢谢!

4

4 回答 4

4

如果您将 xplicitArray 选项设置为 false,则在解析时不会在您没有预料到的地方创建那些数组。像这样:

function parseBody(body) {
    var parseString = require('xml2js').parseString;

    const options = {
        explicitArray: false
    };

    var xml = body
    parseString(xml, options, function (err, result) {
        console.log("cust fname: " + result['soapenv:Envelope']['soapenv:Body']['int:readResponse']['response']['cust']['fName']);
    })
}
var input = '<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:int=\"realURLHere"><soapenv:Header/><soapenv:Body><int:readResponse><response><request>?</request><cust><fName>?</fName></cust></response></int:readResponse></soapenv:Body></soapenv:Envelope>';
parseBody(input);

此外,如果您删除前缀,它可以变得更加清晰:

function parseBody(body) {
    var parseString = require('xml2js').parseString;
    var stripNS = require('xml2js').processors.stripPrefix;

    const options = {
        tagNameProcessors: [stripNS],
        explicitArray: false
    };

    var xml = body
    parseString(xml, options, function (err, result) {
        console.log("cust fname: " + result.Envelope.Body.readResponse.response.cust.fName);
    })
}
var input = '<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:int=\"realURLHere"><soapenv:Header/><soapenv:Body><int:readResponse><response><request>?</request><cust><fName>?</fName></cust></response></int:readResponse></soapenv:Body></soapenv:Envelope>';
parseBody(input);```
于 2019-10-10T21:13:54.853 回答
2

var custFName = result['soapenv:Envelope']['soapenv:Body'][0]['int:realURLHe‌​re'][0]['response'][‌​0]['cust'][0]['fName‌​'];

这解决了我的问题。我的挣扎与这种将所有内容排列在一起的响应有关。如果有更简单的方法或更动态的方法,请告诉我。但就目前而言,这行得通。

于 2017-08-09T17:32:49.477 回答
0

如果您使用的是 NodeJS,我强烈推荐xml2jsxml2js-xpath。这是他们的示例代码,它真正帮助了我。

var xml2js = require("xml2js");
var xpath = require("xml2js-xpath");
 
xml2js.parseString('<root><element id="15">target</element></root>', function(err, json) {

  // find all elements: returns xml2js JSON of the element
  var matches = xpath.find(json, "//element");
 
  // find the first element, and get its id:
  var matches = xpath.evalFirst(json, "//element", "id");
});

于 2018-12-07T16:25:44.863 回答
0

尝试这个

const transform = require('camaro')

const xml = `
<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:int=\"realURLHere">
   <soapenv:Header/>
   <soapenv:Body>
      <int:readResponse>
         <response>
            <request>?</request>
            <cust>
               <fName>hello world</fName>
            </cust>
        </response>
      </int:readResponse>
   </soapenv:Body>
</soapenv:Envelope>
`

const template = {
    fname: '//cust/fName'
}

const result = transform(xml, template)
console.log(JSON.stringify(result, null, 2))

哪个打印出来

{
  "fname": "hello world"
}

您可以通过使用访问result.fname

于 2017-08-10T10:01:35.597 回答