JSON to XML with XSLT 3.0 using saxon

青春壹個敷衍的年華 提交于 2019-12-13 03:36:15

问题


I'm using XSLT 3.0 to transform this document JSON to this document XML with the function json-to-xml,

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

From saxon I pass this json like document XML:

String XML = "<root>" + JSON + "</root>";

I get an XML when call the function json-to-xml:

<?xml version="1.0" encoding="utf-8"?>
<map
    xmlns="http://www.w3.org/2005/xpath-functions">
    <string key="_D">urn:oasis:names:specification:ubl:schema:xsd:Invoice-2</string>
    <string key="_S">urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2</string>
    <string key="_B">urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2</string>
    <array key="Invoice">
        <map>
            <array key="ID">
                <map>
                    <string key="IdentifierContent">123</string>
                </map>
            </array>
            <array key="IssueDate">
                <map>
                    <string key="DateContent">2011-09-22</string>
                </map>
            </array>
            <array key="InvoicePeriod">
                <map>
                    <array key="StartDate">
                        <map>
                            <string key="DateContent">2011-08-01</string>
                        </map>
                    </array>
                    <array key="EndDate">
                        <map>
                            <string key="DateContent">2011-08-31</string>
                        </map>
                    </array>
                </map>
            </array>
            <array key="AccountingSupplierParty">
                <map>
                    <array key="Party">
                        <map>
                            <array key="PartyName">
                                <map>
                                    <array key="Name">
                                        <map>
                                            <string key="TextContent">Custom Cotter Pins</string>
                                        </map>
                                    </array>
                                </map>
                            </array>
                        </map>
                    </array>
                </map>
            </array>
            <array key="AccountingCustomerParty">
                <map>
                    <array key="Party">
                        <map>
                            <array key="PartyName">
                                <map>
                                    <array key="Name">
                                        <map>
                                            <string key="TextContent">North American Veeblefetzer</string>
                                        </map>
                                    </array>
                                </map>
                            </array>
                        </map>
                    </array>
                </map>
            </array>
            <array key="LegalMonetaryTotal">
                <map>
                    <array key="PayableAmount">
                        <map>
                            <number key="AmountContent">100.00</number>
                            <string key="AmountCurrencyIdentifier">CAD</string>
                        </map>
                    </array>
                </map>
            </array>
            <array key="InvoiceLine">
                <map>
                    <array key="ID">
                        <map>
                            <string key="IdentifierContent">1</string>
                        </map>
                    </array>
                    <array key="LineExtensionAmount">
                        <map>
                            <number key="AmountContent">100.00</number>
                            <string key="AmountCurrencyIdentifier">CAD</string>
                        </map>
                    </array>
                    <array key="Item">
                        <map>
                            <array key="Description">
                                <map>
                                    <string key="TextContent">Cotter pin, MIL-SPEC</string>
                                </map>
                            </array>
                        </map>
                    </array>
                </map>
            </array>
        </map>
    </array>
</map>

Is it correct pass this XML as parameter?

<xsl:apply-templates select="$input-as-xml" />

Please, any suggestion in how can I use templates to transform the XML that I want? I just want some suggestions.


回答1:


The information about prefixes does not seem to be included in the JSON so I have decided to declare them as parameters and I have assumed you know the name/key of the element to start with (e.g. Invoice):

<?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"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    exclude-result-prefixes="xs math fn"
    version="3.0">

    <xsl:param name="json-input" as="xs:string">{"_D":"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2",
        "_S":"urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2",
        "_B":"urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2",
        "Invoice":[{
        "ID":[{"IdentifierContent":"123"}],
        "IssueDate":[{"DateContent":"2011-09-22"}],
        "InvoicePeriod":[{
        "StartDate":[{"DateContent":"2011-08-01"}],
        "EndDate":[{"DateContent":"2011-08-31"}]
        }],
        "AccountingSupplierParty":[{
        "Party":[{
        "PartyName":[{
        "Name":[{"TextContent":"Custom Cotter Pins"}]
        }]
        }]
        }],
        "AccountingCustomerParty":[{
        "Party":[{
        "PartyName":[{
        "Name":[{"TextContent":"North American Veeblefetzer"}]
        }]
        }]
        }],
        "LegalMonetaryTotal":[{
        "PayableAmount":[{"AmountContent":100.00,
        "AmountCurrencyIdentifier":"CAD"}]
        }],
        "InvoiceLine":[{
        "ID":[{"IdentifierContent":"1"}],
        "LineExtensionAmount":[{"AmountContent":100.00,
        "AmountCurrencyIdentifier":"CAD"}],
        "Item":[{
        "Description":[{"TextContent":"Cotter pin, MIL-SPEC"}]
        }]
        }]
        }]}</xsl:param>

    <xsl:param name="prefix2" as="xs:string" select="'cbc'"/>
    <xsl:param name="prefix1" as="xs:string" select="'cac'"/>

    <xsl:output indent="yes"/>

    <xsl:template name="xsl:initial-template">
        <xsl:apply-templates select="json-to-xml($json-input)//fn:array[@key = 'Invoice']"/>
    </xsl:template>

    <xsl:template match="fn:array[@key = 'Invoice']" priority="5">
        <xsl:variable name="ns" select="../fn:string[@key = '_D']"/>
        <xsl:variable name="ns1" select="../fn:string[@key = '_S']"/>
        <xsl:variable name="ns2" select="../fn:string[@key = '_B']"/>
        <xsl:element name="{@key}" namespace="{$ns}">
            <xsl:namespace name="{$prefix1}" select="$ns1"/>
            <xsl:namespace name="{$prefix2}" select="$ns2"/>
            <xsl:apply-templates>
                <xsl:with-param name="ns1" select="$ns1" tunnel="yes"/>
                <xsl:with-param name="ns2" select="$ns2" tunnel="yes"/>
            </xsl:apply-templates>
        </xsl:element>
    </xsl:template>

    <xsl:template match="fn:array[@key and *[1][self::fn:map[fn:string]] and not(*[2])]">
        <xsl:param name="ns2" tunnel="yes"/>
        <xsl:element name="{$prefix2}:{@key}" namespace="{$ns2}">
            <xsl:value-of select="fn:map/fn:string"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="fn:array[@key and fn:map[fn:array]]">
        <xsl:param name="ns1" tunnel="yes"/>
        <xsl:element name="{$prefix1}:{@key}" namespace="{$ns1}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>



回答2:


JSON to XML Example:

JSON: "

"{\n" +"    \"color\": \"red\",\n" +" \"value\": \"#f00\"\n" +"}";

XSLT:

<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="jsonText"></xsl:param>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template name="init">
    <xsl:apply-templates select="json-to-xml($jsonText)"/>
</xsl:template>
<xsl:template match="string[@key = 'subjects']" xpath-default namespace="http://www.w3.org/2005/xpath-functions"><xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:sequence select="parse-xml(.)/node()"/></xsl:copy></xsl:template</xsl:stylesheet>`


来源:https://stackoverflow.com/questions/46085295/json-to-xml-with-xslt-3-0-using-saxon

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!