在 NodeJs 中使用 fast-xml-parser 将特定标签解析为数组
Posted
技术标签:
【中文标题】在 NodeJs 中使用 fast-xml-parser 将特定标签解析为数组【英文标题】:parsing a particular tag as array using fast-xml-parser in NodeJs 【发布时间】:2021-07-15 12:50:41 【问题描述】:我在我的代码中使用 fast-xml-parser 将 xml 字符串转换为 JSON。问题出在 XML 我有一个包含元素数组的标签,但是当我们在这个标签内只收到一个元素时,这个标签内的值会被解析为 JSON 对象而不是 JSON 数组但是当有多个值时被解析为数组。
以下是标签中只有一个元素时我收到的示例和输出
xmlString = `<Items>
<Item sn="abcd"/>
</Items>`
输出: Items: Item: attributes: [Object]
以下是包含多个元素时的示例和输出
xmlString = `<Items>
<Item sn="abcd"/>
<Item sn="efgh"/>
</Items>`
输出: Item: [ attributes: [Object] , attributes: [Object] ]
有没有办法修复它,以便每次我将 Item 作为 JSON 数组而不是 JSON 对象接收?
【问题讨论】:
你的预期输出是什么? 【参考方案1】:根据docs有一个相当灵活的选项arrayMode
:
false
时,单次出现的标签被解析为对象,如果出现多次,则被解析为数组。当true
时,标签将被解析为一个始终不包括叶节点的数组。当strict
时,所有标签将仅被解析为数组。当RegEx
的实例时,只有标签将被解析为匹配正则表达式的数组。当function
一个标签名称被传递给可以检查的回调。
在你的情况下,一个简单的正则表达式就可以了。不确定它是否需要 /Items/
或 /Item/
- 但您肯定可以立即测试它。
应导致Item
被检索为数组的示例:
arrayMode: /Item/
arrayMode: tagName => tagName === 'Item'
【讨论】:
感谢您的回复。我看到 arryMode 是一个布尔值,当设置为 true 时,它将所有复杂的标签转换为一个数组。您能否分享一个示例,说明如何在仅将选择性标记解析为数组的选项中使用正则表达式? 我尝试了三种组合,但似乎不起作用。arrayMode: [/Items/,/Item/]
,arrayMode: [/Items/]
,arrayMode: [/Item/]
@ShailendraChoudhary 我编辑了帖子,arrayMode
本身不应该是一个数组。
@stock-overlflaw :感谢您的解决方案!第一个不适合我,因为我的 XML 中有另一个名为“PackedItems”的标签应该被解析为对象,但由于正则表达式而被解析为数组,而且我有多个这样的标签。我用了这个arrayMode: tagName => ['Item', 'Transaction'].includes(tagName)
,它奏效了。【参考方案2】:
或者,您也可以使用 camaro 来转换输出,使其与您想要的一致
您可以重命名字段,使用基于 xpath 的模板调整输出。
在下面的示例中,您指定输出的属性items
是一个数组,那么输出将始终是一个数组
例子
var transform = require("camaro")
async function main()
var xmlString = `<Items>
<Item sn="abcd"/>
</Items>`
var template =
items: ['Items/Item',
sn: '@sn'
]
var output = await transform(xmlString, template)
console.log(JSON.stringify(output, null, 4))
main()
输出
"items": [
"sn": "abcd"
]
【讨论】:
似乎与 Camaro 我必须在模板中提供所有标签。因此,如果还有 1000 个元素(字符串和复杂值的混合),我必须将它们全部包含在模板中。这种理解正确吗? @ShailendraChoudhary 是的。这是一种塑造输出对象的方法,所以我们必须在模板中写下我们想要的一切以上是关于在 NodeJs 中使用 fast-xml-parser 将特定标签解析为数组的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Nodejs 中使用 document.getElementById()