将XML转换为JSON的XSL

14

输入XML

<Root>
    <Result>
        <System>
            <Name>ABC</Name>
            <ID pname="PAD">
                <value>4567</value>
            </ID>
            <lastTime>2013-11-06T17:36:46.000-05:00</lastTime>
        </System>
        <line>Metals</line>
    </Result>
    <Result>
        <System>
            <Name>CAYS</Name>
            <ID pname="PAD">
                <value>MCIERT</value>
            </ID>
            <ID pname="ATPAD">
                <value>56412</value>
            </ID>
            <lastTime>2013-12-06T16:43:36.000-05:00</lastTime>
        </System>
        <System>
            <Name>CAYS</Name>
            <ID pname="CAD">
                <value>DGSG</value>
            </ID>
            <ID pname="ARCAD">
                <value>2847114</value>
            </ID>
            <lastTime>2013-12-07T20:02:38.000-05:00</lastTime>
        </System>
        <line>Minerals</line>
    </Result>
</Root>

输出 Json

{
"Root": {
"Result": [
  {
    "System": {
      "Name": "ABC",
      "ID": {
        "pname": "PAD",
        "value": "4567"
      },
      "lastTime": "2013-11-06T17:36:46.000-05:00"
    },
    "line": "Metals"
  },
  {
    "System": [
      {
        "Name": "CAYS",
        "ID": [
          {
            "pname": "PAD",
            "value": "MCIERT"
          },
          {
            "pname": "ATPAD",
            "value": "56412"
          }
        ],
        "lastTime": "2013-12-06T16:43:36.000-05:00"
      },
      {
        "Name": "CAYS",
        "ID": [
          {
            "pname": "CAD",
            "value": "DGSG"
          },
          {
            "pname": "ARCAD",
            "value": "2847114"
          }
        ],
        "lastTime": "2013-12-07T20:02:38.000-05:00"
      }
    ],
    "line": "Minerals"
  }
]
}
}

如何编写通用的XSLT样式表,将输入的XML转换为JSON。

输入可能在根节点下有很多结果,在结果下有系统和名称,在系统下有ID名称和值。

2个回答

28

我在这里复制和粘贴了下面的XSLT,它应该可以帮助你将XML转换为JSON。谢谢 :)

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:template match="/">{
    <xsl:apply-templates select="*"/>}
</xsl:template>

<!-- Object or Element Property-->
<xsl:template match="*">
    "<xsl:value-of select="name()"/>" :<xsl:call-template name="Properties">
        <xsl:with-param name="parent" select="'Yes'"> </xsl:with-param>
    </xsl:call-template>
</xsl:template>

<!-- Array Element -->
<xsl:template match="*" mode="ArrayElement">
    <xsl:call-template name="Properties"/>
</xsl:template>

<!-- Object Properties -->
<xsl:template name="Properties">
    <xsl:param name="parent"></xsl:param>
    <xsl:variable name="childName" select="name(*[1])"/>
    <xsl:choose>            
        <xsl:when test="not(*|@*)"><xsl:choose><xsl:when test="$parent='Yes'"> <xsl:text>&quot;</xsl:text><xsl:value-of select="."/><xsl:text>&quot;</xsl:text></xsl:when>
                <xsl:otherwise>"<xsl:value-of select="name()"/>":"<xsl:value-of  select="."/>"</xsl:otherwise>
            </xsl:choose>           
        </xsl:when>                
        <xsl:when test="count(*[name()=$childName]) > 1">{ "<xsl:value-of  select="$childName"/>" :[<xsl:apply-templates select="*" mode="ArrayElement"/>] }</xsl:when>
        <xsl:otherwise>{
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="*"/>
            }</xsl:otherwise>
    </xsl:choose>
    <xsl:if test="following-sibling::*">,</xsl:if>
</xsl:template>

<!-- Attribute Property -->
<xsl:template match="@*">"<xsl:value-of select="name()"/>" : "<xsl:value-of select="."/>",
</xsl:template>
</xsl:stylesheet>

我正在检查这个。 - Isaac G Sivaa
请查看已编辑的XSL。工作正常。之前在一个仅包含文本子元素而不是任何父调用部分的元素中出现了错误。 - Isaac G Sivaa
4
有一些现有的XSLT,是通用的(https://gist.github.com/inancgumus/3ce56ddde6d5c93f3550b3b4cdc6bcb8)。 - sancelot
@IsaacGSivaa,你能给一个提示如何处理输出JSON中的空格和空行吗? - Vinod Srivastav
1
非常有用,但如果XML节点内包含双引号字符串,则会产生无效JSON。 - Luis Miguel Serrano
显示剩余3条评论

0

@sancelot 发表了带有指向 GitHub 样式表的链接的评论,我已经对其与回答实例一起进行了测试(并且已经点赞)。以下是更多详细信息,以展示以下示例。

示例 XML:

<avpList>
  <eComStringAttributeValuePairList attributeName="orderTypeCode" qualifierCodeName="order" qualifierCodeList="OrderTypeCode" qualifierCodeListVersion="2">220</eComStringAttributeValuePairList>
  <eComStringAttributeValuePairList attributeName="orderPriority">647</eComStringAttributeValuePairList>
  <eComStringAttributeValuePairList attributeName="customerDocumentReference">0</eComStringAttributeValuePairList>
</avpList>

如果我有一个混合属性节点值并使用了被赞的答案,我将得到以下输出:
            "avpList": {
            "eComStringAttributeValuePairList": [
                {
                    "attributeName": "orderTypeCode",
                    "qualifierCodeName": "order",
                    "qualifierCodeList": "OrderTypeCode",
                    "qualifierCodeListVersion": "2",
                },
                {
                    "attributeName": "orderPriority",
                },
                {
                    "attributeName": "customerDocumentReference",
                }
            ]
        }

通过 JSONLint 运行它,可以显示尾随逗号的问题以及缺少元素值的问题。

Error: Parse error on line 30: ...Version": "2",                    }

使用 XML Spy 2019 解析脚本。

使用注释的 Github 链接并解析会产生以下 JSON,第一次通过 linter 验证。请注意,如果您期望在 JSON 中有任何形式的类型数据,则样式表都不支持。

            "avpList": {
            "eComStringAttributeValuePairList": [
                {
                    "attributeName": "orderTypeCode",
                    "qualifierCodeName": "order",
                    "qualifierCodeList": "OrderTypeCode",
                    "qualifierCodeListVersion": "2",
                    "text": "220"
                },
                {
                    "attributeName": "orderPriority",
                    "text": "647"
                },
                {
                    "attributeName": "customerDocumentReference",
                    "text": "0"
                }
            ]
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接