使用 XSLT 3.0 将 JSON 转换为 XML ,操作输出

Convert JSON to XML using XSLT 3.0 , manipulate the output

我想将 JSON 数据转换为 xml。为此,我使用函数 json-to-xml。

JSON

{
    "example": {
        "items": [
            {
                "_links": {
                    "self": {
                        "href": "xxx"
                    }
                },
                "test": "123",
                "nummer": "456",
                "parent": null,
                "category": [
                    "test"
                ],
                "select": true,
                "values": {
                    "abc": [
                        {
                            "test": null,
                            "data": 2
                        }
                    ]
                },
                "cpu": {
                    "1": {
                        "cpus": []
                    },
                    "3": {
                        "cpus": []
                    },
                    "4": {
                        "cpus": [
                            "cpu1"]
                    },
                    "5": {
                        "cpus": [
                            "cpu6"
                        ]
                    }
                }
            },
                    {
                "_links": {
                    "self": {
                        "href": "xxx"
                    }
                },
                "test": "789",
                "nummer": "4110",
                "parent": null,
                "category": [
                    "test"
                ],
                "select": true,
                "values": {
                    "abc": [
                        {
                            "test": null,
                            "data": 2
                        }
                    ]
                },
                "cpu": {
                    "1": {
                        "cpus": []
                    },
                    "3": {
                        "cpus": []
                    },
                    "4": {
                        "cpus": [
                            "cpu3"
                        ]
                    },
                    "5": {
                        "cpus": [
                            "cpu4",
                            "cpu5"
                        ]
                    }
                }
            }    
        ]
    }
}

我使用的xslt:

<xsl:param name="input" select="'url json'"/>
    <xsl:template name="initial">
            <xsl:apply-templates select="json-to-xml(unparsed-text($input))" mode="copy"/>
        </xsl:template>

        <xsl:template match="node() | @*" mode="copy">
            <xsl:copy>
                <xsl:apply-templates select="node() | @*" mode="copy"/>
            </xsl:copy>
        </xsl:template>   

结果有这样的结构:

<map xmlns="http://www.w3.org/2005/xpath-functions">
   <map key="example">
      <array key="items">
         <map>
            <map key="_links">
               <map key="self">
                  <string key="href">xxx</string>
               </map>
            </map>
            <string key="test">123</string>
            <string key="nummer">456</string>
            <null key="parent"/>
            <array key="category">
               <string>test</string>
            </array>
            <boolean key="select">true</boolean>
            <map key="values">
               <array key="abc">
                  <map>
                     <null key="test"/>
                     <number key="data">2</number>
                  </map>
               </array>
            </map>
            <map key="cpu">
               <map key="1">
                  <array key="cpus"/>
               </map>
               <map key="3">
                  <array key="cpus"/>
               </map>
               <map key="4">
                  <array key="cpus">
                     <string>cpu1</string>
                  </array>
               </map>
               <map key="5">
                  <array key="cpus">
                     <string>cpu6</string>
                  </array>
               </map>
            </map>
         </map>
         <map>
            <map key="_links">
               <map key="self">
                  <string key="href">xxx</string>
               </map>
            </map>
            <string key="test">789</string>
            <string key="nummer">4110</string>
            <null key="parent"/>
            <array key="category">
               <string>test</string>
            </array>
            <boolean key="select">true</boolean>
            <map key="values">
               <array key="abc">
                  <map>
                     <null key="test"/>
                     <number key="data">2</number>
                  </map>
               </array>
            </map>
            <map key="cpu">
               <map key="1">
                  <array key="cpus"/>
               </map>
               <map key="3">
                  <array key="cpus"/>
               </map>
               <map key="4">
                  <array key="cpus">
                     <string>cpu3</string>
                  </array>
               </map>
               <map key="5">
                  <array key="cpus">
                     <string>cpu4</string>
                     <string>cpu5</string>
                  </array>
               </map>
            </map>
         </map>
      </array>
   </map>
</map>

这就是我想要的。

    <?xml version="1.0" encoding="UTF-8"?>
<example>
    <items>
        <_links>
            <self>
                <href>xxx</href>
            </self>
        </_links>
        <test>123</test>
        <nummer>456</nummer>
        <parent>null</parent>
        <category>test</category>
        <select>true</select>
        <values>
            <abc>
                <test>null</test>
                <data>2</data>
            </abc>
        </values>
        <cpu>
            <_1></_1>
            <_3></_3>
            <_4>
                <cpus>cpu1</cpus>
            </_4>
            <_5>
                <cpus>cpu6</cpus>
            </_5>
        </cpu>
    </items>
    <items>
        <_links>
            <self>
                <href>xxx</href>
            </self>
        </_links>
        <test>789</test>
        <nummer>4110</nummer>
        <parent>null</parent>
        <category>test</category>
        <select>true</select>
        <values>
            <abc>
                <test>null</test>
                <data>2</data>
            </abc>
        </values>
        <cpu>
            <_1></_1>
            <_3></_3>
            <_4>
                <cpus>cpu3</cpus>
            </_4>
            <_5>
                <cpus>cpu4</cpus>
                <cpus>cpu5</cpus>
            </_5>
        </cpu>
    </items>
</example>

我想删除关键属性。另外元素 "items" 应该是 xml 结构的一部分。 有人能解决这个问题吗?

提前致谢!

你可以试试这个:

    <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="3.0">
    <xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="*[@key]">
        <xsl:element name="{@key}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

将模式设置为仅复制文本,并添加模板以将具有键的元素转换为该键的元素,如果键不是 QName,则进行一些错误更正:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="#all">

    <xsl:param name="input" select="'input.json'"/>

    <xsl:output indent="yes"/>

    <xsl:function name="mf:element-name" as="xs:QName">
        <xsl:param name="key" as="xs:string"/>
        <xsl:try select="xs:QName($key)">
            <xsl:catch select="xs:QName('_' || $key)"/>
        </xsl:try>
    </xsl:function>

    <xsl:mode name="strip" on-no-match="text-only-copy"/>

    <xsl:template name="xsl:initial-template" match="/">
        <xsl:apply-templates select="json-to-xml(unparsed-text($input))" mode="strip"/>
    </xsl:template>

    <xsl:template match="*[@key]" mode="strip">
        <xsl:element name="{mf:element-name(@key)}">
            <xsl:apply-templates mode="#current"/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>