Разбор с xml2js

Я новичок в node.js и надо разбирать XML, В JS я просто использую DOMParser и использовать getElementsByTagName чтобы получить ценности, которые я желаю. Я только что переключился на узел и использую 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] ] 
   } 
}

Я пытаюсь получить доступ к значению <fName> в <cust> но не повезло. Любая помощь будет оценена. Спасибо!

2 ответа

Если вы установите для параметра 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);```

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

Это решило мою проблему. Моя борьба была связана с этим ответом, имеющим все в массиве. Если есть более простой способ сделать это или что-то более динамичное, пожалуйста, дайте мне знать. Но пока это работает.

Если вы используете NodeJS, я настоятельно рекомендую xml2js & xml2js-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");
});

Попробуй это

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

Другие вопросы по тегам