【问题标题】:How to force xml2js to output array for certain keys?如何强制 xml2js 为某些键输出数组?
【发布时间】:2019-10-18 10:11:46
【问题描述】:

我有一些 XML,我希望它输出到一个数组中。但是当只有一项存在时,xml2js 将一项输出到一个对象。当有多个项目时,它作为一个数组输出。为了一致性,我如何强制它成为一个数组?

我的 XML 如下所示:

const xml = `<Shift>
    <Transaction>
      <Currency>GBP</Currency>
      <Amount>24.50</Amount>
    </Transaction>
</Shift>`

parseStringPromise(xml).then(json => console.log(JSON.stringify(json)))

你可以看到输出为:

{
  "Transaction": {
    "Currency": "GBP",
    "Amount": "24.50"
  }
}

但通常有多个交易。所以通常 XML 看起来像这样:

const xml = `<Shift>
    <Transaction>
      <Currency>GBP</Currency>
      <Amount>24.50</Amount>
    </Transaction>
    <Transaction>
      <Currency>GBP</Currency>
      <Amount>25.50</Amount>
    </Transaction>
    <Transaction>
      <Currency>GBP</Currency>
      <Amount>26.50</Amount>
    </Transaction>
    <Transaction>
      <Currency>GBP</Currency>
      <Amount>27.50</Amount>
    </Transaction>
</Shift>`

parseStringPromise(xml).then(json => console.log(JSON.stringify(json)))

像这样输出到数组中

{
  "Transaction": [
    {
      "Currency": "GBP",
      "Amount": "24.50"
    },
    {
      "Currency": "GBP",
      "Amount": "25.50"
    },
    {
      "Currency": "GBP",
      "Amount": "26.50"
    },
    {
      "Currency": "GBP",
      "Amount": "27.50"
    }
  ]
}

如何确保即使 xml 中只有 1 个 Transaction 项,它也会输出到数组?

我需要将选项传递给解析器还是需要重新格式化 XML?

【问题讨论】:

    标签: javascript node.js json xml parsing


    【解决方案1】:

    市面上有很多 XML 到 JSON 的转换器,它们都有这种问题。他们在某些情况下会做你想做的事,而在其他情况下则不会,而且他们都没有提供太多的控制权。如果您想控制生成的 JSON,我建议您使用 XSLT 3.0:这允许您在调用 xml-to-json() 进行转换之前将 XML 转换为与您想要生成的 JSON 的结构相对应。

    【讨论】:

      【解决方案2】:

      您可以为此目的使用camaro。 camaro 让您编写一个基于 xpath 的模板来指定您希望输出的方式。在这种情况下,您指定要从中取出一个数组

      const { transform } = require('camaro')
      const xml = `<Shift>
          <Transaction>
            <Currency>GBP</Currency>
            <Amount>24.50</Amount>
          </Transaction>
          <Transaction>
            <Currency>GBP</Currency>
            <Amount>25.50</Amount>
          </Transaction>
          <Transaction>
            <Currency>GBP</Currency>
            <Amount>26.50</Amount>
          </Transaction>
          <Transaction>
            <Currency>GBP</Currency>
            <Amount>27.50</Amount>
          </Transaction>
      </Shift>`
      
      ;(async function () {
          const template = {
              transactions: ['/Shift/Transaction', {
                  Currency: 'Currency',
                  Amount: 'Amount'
              }]
          }
      
          console.log(await transform(xml, template));
      
      })()
      

      输出

      { transactions:
         [ { Currency: 'GBP', Amount: '24.50' },
           { Currency: 'GBP', Amount: '25.50' },
           { Currency: 'GBP', Amount: '26.50' },
           { Currency: 'GBP', Amount: '27.50' } ] }
      

      即使只有 1 个元素

      const { transform } = require('../')
      const xml = `<Shift>
          <Transaction>
            <Currency>GBP</Currency>
            <Amount>24.50</Amount>
          </Transaction>
      </Shift>`
      
      ;(async function () {
          const template = {
              transactions: ['/Shift/Transaction', {
                  Currency: 'Currency',
                  Amount: 'Amount'
              }]
          }
      
          console.log(await transform(xml, template));
      
      })()
      

      输出

      { transactions: [ { Currency: 'GBP', Amount: '24.50' } ] }
      

      【讨论】:

        猜你喜欢
        • 2013-12-12
        • 1970-01-01
        • 1970-01-01
        • 2020-08-31
        • 2012-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多