问题描述
当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' }
]
}