0

当 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', 'w2', 'w3'],
k: ['w4'],
q:[ { _: 'w4mod', '$$': { x: [ 'a' ] } }],
w: [ 'w5', 'w6'],
k: ['w7'],
q: ['w7', 'Mod7'],
w: ['w8']
}

ETC

有什么方法可以维护这些信息的顺序吗?

4

2 回答 2

0

您可以为此使用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' },
    { key: 'w', value: 'w3' },
    { key: 'k', value: 'w4' },
    { key: 'q', value: 'w4moda' },
    { key: 'w', value: 'w5' },
    { key: 'w', value: 'w6' },
    { key: 'k', value: 'w7' },
    { key: 'q', value: 'w7' },
    { key: 'q', value: 'Mod7' },
    { key: 'w', value: 'w8' }
  ]
}
于 2020-09-25T03:40:46.553 回答
0

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

尝试这个:

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

$$您应该从以下密钥中获得保留的顺序explicitChildren

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

此问题也可能与此有关:httpscharsAsChildren ://github.com/Leonidas-from-XIV/node-xml2js/issues/499 但如果没有该选项,它似乎可以正常工作。

否则,这个库可能会帮助你:https ://github.com/nashwaan/xml-js

于 2020-09-24T13:45:21.687 回答