使用XSLT将json数组转换为xml

时间:2018-06-25 14:18:55

标签: json xml xslt

我有一个前端页面,该页面将请求发送到部署到wso2控制台的数据服务以在表中进行更新。 问题是我需要将前端的json数组转换为xml格式,以便为请求构建有效负载工厂。 json是:

{"cdcList":
["UpdateCdc":
    {
 "idCdc":1,
     "order":1,
     "cdcName":"test 1",
    },
 "UpdateCdc":
    {
     "idCdc":2,
 "order":2,
     "cdcName":"test 2",
     "idParent":1
    },
  "UpdateCdc":
    {
     "idCdc":3,
     "order":1,
     "cdcName":"test 3",
     "idParent":1
     }
]

}

,而我希望它在xml中的期望结果是:

<cdcList>
          <UpdateCdc>
        <idCdc>1</idCdc>
        <order>1</order>
            <cdcName>test 1</cdcName>
          </UpdateCdc>
          <UpdateCdc>
            <idCdc>2</idCdc>
            <order>2</order>
            <cdcName>test 2</cdcName>
            <idParent>1</idParent>
          </UpdateCdc>
          <UpdateCdc>
            <idCdc>3</idCdc>
            <order>3</order>
            <cdcName>test 3</cdcName>
            <idParent>1</idParent>
          </UpdateCdc>
</cdcList>

谢谢。

2 个答案:

答案 0 :(得分:1)

要在XSLT中进行客户端处理并支持JSON解析,您将需要XSLT 3.0处理器,实际上这是指Saxon-JS。 (免责声明:这是我公司的产品。)

很遗憾,您提供的输入不是有效的JSON,但让我们假设它实际上是这样的:

[
    {
        "idCdc": 1,
        "order": 1,
        "cdcName": "test 1"
    },
    {
        "idCdc": 2,
        "order": 2,
        "cdcName": "test 2",
        "idParent": 1
    },
    {
        "idCdc": 3,
        "order": 1,
        "cdcName": "test 3",
        "idParent": 1
    }
]

然后,您可以使用以下XSLT 3.0代码将其转换为所需的XML格式:

<xsl:variable name="json-array" select="json-doc('input.json')"/>
<cdcList>
  <xsl:for-each select="$json-array?*">
    <updateCdc>
      <xsl:for-each select="map:keys(.)">
         <xsl:element name="{.}">
           <xsl:value-of select="map:get(.)"/>
         </xsl:element>
      </xsl:for-each>
    </updateCdc>
  </xsl:for-each>
</cdcList>

答案 1 :(得分:0)

虽然Michael Kay的答案为您提供了XML(可在https://xsltfiddle.liberty-development.net/bFDb2Cf/上在线查看),但我认为它有一个缺点,因为未定义XPath 3.1映射的键顺序,因此您可以使用map:keys获取子元素的任何顺序(例如,在链接的示例中为idParentidCdccdcNameorder),而您可能想定义子元素的顺序元素基于JSON中的顺序。可以使用蒂姆在评论中已经提到的json-to-xml函数来实现:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:array="http://www.w3.org/2005/xpath-functions/array"
    exclude-result-prefixes="xs math map array fn"
    version="3.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:param name="json-input" as="xs:string">[
    {
        "idCdc": 1,
        "order": 1,
        "cdcName": "test 1"
    },
    {
        "idCdc": 2,
        "order": 2,
        "cdcName": "test 2",
        "idParent": 1
    },
    {
        "idCdc": 3,
        "order": 1,
        "cdcName": "test 3",
        "idParent": 1
    }
]</xsl:param>

  <xsl:variable name="json-array" select="parse-json($json-input)"/>

  <xsl:variable name="json-xml" select="json-to-xml($json-input)"/>

  <xsl:template match="/">
    <cdcList>
        <xsl:apply-templates select="$json-xml/*"/>
    </cdcList>
  </xsl:template>

  <xsl:template match="fn:map">
      <updateCdc>
          <xsl:apply-templates/>
      </updateCdc>
  </xsl:template>

  <xsl:template match="fn:map/fn:*">
      <xsl:element name="{@key}">
          <xsl:value-of select="."/>
      </xsl:element>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/bFDb2Cf/2就是一个例子,在https://xsltfiddle.liberty-development.net/bFDb2Cf/1中,我还输出了json-to-xml调用的结果,以便您可以看到JSON输入如何映射到XML:

<array xmlns="http://www.w3.org/2005/xpath-functions">
   <map>
      <number key="idCdc">1</number>
      <number key="order">1</number>
      <string key="cdcName">test 1</string>
   </map>
   <map>
      <number key="idCdc">2</number>
      <number key="order">2</number>
      <string key="cdcName">test 2</string>
      <number key="idParent">1</number>
   </map>
   <map>
      <number key="idCdc">3</number>
      <number key="order">1</number>
      <string key="cdcName">test 3</string>
      <number key="idParent">1</number>
   </map>
</array>