xml2js返回的数组不能保持所有顺序

问题描述

当xml元素捆绑在一起时,某些顺序将丢失。

例如,我正在读取的xml具有如下元素:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<b>
  <c n="1">
    <v n="1">
      <w>w1</w>
      <w>w2</w>
      <w>w3</w>
      <k>w4</k>
      <q>w4mod<x>a</x></q>
      <w>w5</w>
      <w>w6</w>
      <k>w7</k>
      <q>w7</q>
      <q>Mod7</q>
      <w>w8</w>
    </v>
  </c>
</b>

可以有任意数量<w> something </w>条目和0或更多<k>something</k>条目以及0或更多<q> something </q>条目。

但是我需要在解析中保持顺序。当我使用以下代码时:

    xml2js = require('xml2js'),util = require('util');

var parser = new xml2js.Parser({explicitChildren: true},{preserveChildrenorder:true});

fs.readFile(__dirname + '/Test.xml',function(err,data) {
    parser.parseString(data,function (err,result) {
        console.log(util.inspect(result,false,null,true))
    });
});

我得到:

  b: {
    '$$': {
      c: [
        {
          '$': { n: '1' },'$$': {
            v: [
              {
                '$': { n: '1' },'$$': {
                  w: [ 'w1','w2','w3','w5','w6','w8' ],k: [ 'w4','w7' ],q: [
                    { _: 'w4mod','$$': { x: [ 'a' ] } },'w7','Mod7'
                  ]
                }
              }
            ]
          }
        }
      ]
    }
  }
}

我想要的是类似的东西

w: [ 'w1','w3'],k: ['w4'],q:[ { _: 'w4mod','$$': { x: [ 'a' ] } }],w: [ 'w5','w6'],k: ['w7'],q: ['w7','Mod7'],w: ['w8']
}

有什么方法可以维护此信息的顺序?

解决方法

构造函数需要 1个参数new xml2js.Parser({optionName: value})。 您提供了 2个参数

尝试一下:

var parser = new xml2js.Parser({explicitChildren: true,preserveChildrenOrder:true});

您应该通过$$的{​​{1}}键获得保留的订单:

explicitChildren

此问题也可能与以下问题有关:https://github.com/Leonidas-from-XIV/node-xml2js/issues/499,但似乎没有v: [ { $: { n: '1' },$$: [ { _: 'w1','#name': 'w' },{ _: 'w2',{ _: 'w3',{ _: 'w4','#name': 'k' },{ _: 'w4mod','#name': 'q',$$: [{ _: 'a','#name': 'x' }],x: ['a'] },{ _: 'w5',{ _: 'w6',{ _: 'w7','#name': 'q' },{ _: 'Mod7',{ _: 'w8','#name': 'w' } ],w: ['w1','w2','w3','w5','w6','w8'],k: ['w4','w7'],q: [ { _: 'w4mod','w7','Mod7' ] } ] 选项也可以正常工作。

否则,该库可能会帮助您:https://github.com/nashwaan/xml-js

,

您可以为此使用camaro。 camaro的缺点是您需要事先了解xml的结构。

这是怎么做

const { transform } = require('camaro')

async function main() {
    const xml = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <b>
      <c n="1">
        <v n="1">
          <w>w1</w>
          <w>w2</w>
          <w>w3</w>
          <k>w4</k>
          <q>w4mod<x>a</x></q>
          <w>w5</w>
          <w>w6</w>
          <k>w7</k>
          <q>w7</q>
          <q>Mod7</q>
          <w>w8</w>
        </v>
      </c>
    </b>`

    const template = {
        items: ['/b/c/v/node()',{
            key: 'name()',// get node name of the current child
            value: '.' // get text of the current child. can add more field as well
        }]
    }

    console.log(await transform(xml,template));
}

main()

输出:

{
  items: [
    { key: 'w',value: 'w1' },{ key: 'w',value: 'w2' },value: 'w3' },{ key: 'k',value: 'w4' },{ key: 'q',value: 'w4moda' },value: 'w5' },value: 'w6' },value: 'w7' },value: 'Mod7' },value: 'w8' }
  ]
}