将XML转换为JSON时,使用XSLT删除JSON中的根标记

时间:2015-05-26 06:02:52

标签: json xml xslt

我正在尝试使用XSLT定义将XML转换为JSON。我有所需的输出,但我希望我的json输出中的根标记在转换时被删除请帮我解决。

XML输入

<ArrayOfApiInvoiceReport xmlns="http://schemas.datacontract.org/2004/07/RepSpark.WebServices.Models">
    <BillingAddress1>10 N LUMINA AVE</BillingAddress1>
    <BillingAddress2/>
    <BillingCity>WRIGHTSVILLE BEACH</BillingCity>
    <BillingCountry>US</BillingCountry>
    <BillingCustomerCode>3003800</BillingCustomerCode>
    <BillingCustomerName>SWEETWATER SURF SHOP</BillingCustomerName>
    <BillingState>NC</BillingState>
    <BillingZip>28480</BillingZip>
    <InvoiceAmount>372.72</InvoiceAmount>
    <InvoiceCreatedDate>20141110</InvoiceCreatedDate>
    <InvoiceItems>
        <InvoiceItemSizes>
            <InvoiceLineNumber>1</InvoiceLineNumber>
            <InvoicedQuantity>3</InvoicedQuantity>
            <SizeCode>L</SizeCode>
            <UPC>9348282095644</UPC>
        </InvoiceItemSizes>
        <InvoiceLineNumber>1</InvoiceLineNumber>
        <InvoiceNumber>101000005</InvoiceNumber>
    <InvoiceItems>
</ArrayOfApiInvoiceReport

使用XSLT

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

<!-- Object or Element Property-->
<xsl:template match="*">
    <xsl:call-template name="Properties"/>
</xsl:template>

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

<!-- Object Properties -->
<xsl:template name="Properties">
    <xsl:variable name="childName" select="name(*[1])"/>
    <xsl:choose>
        <xsl:when test="not(*|@*)">"<xsl:value-of select="."/>"</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>

当前JSON输出

"ArrayOfApiInvoiceReport" : [{

    "BillingAddress1" : "10 N LUMINA AVE",
    "BillingAddress2" : "",
    "BillingCity" : "WRIGHTSVILLE BEACH",
    "BillingCountry" : "US",
    "BillingCustomerCode" : "3003800",
    "BillingCustomerName" : "SWEETWATER SURF SHOP",
    "BillingState" : "NC",
    "BillingZip" : "28480",
    "InvoiceAmount" : "372.72",
    "InvoiceCreatedDate" : "20141110",
    "InvoiceItems" : [{

    "InvoiceItemSizes" : [{

    "InvoiceLineNumber" : "1",
    "InvoicedQuantity" : "3",
    "SizeCode" : "L",
    "UPC" : "9348282095644"
}],
    "InvoiceLineNumber" : "1",
    "InvoiceNumber" : "101000005",
    "InvoicedQuantity" : "3",

必需输出是没有"ArrayOfApiInvoiceReport" [{

}的JSON
"BillingAddress1": "10 N LUMINA AVE",
"BillingAddress2": "",
"BillingCity": "WRIGHTSVILLE BEACH",
"BillingCountry": "US",
"BillingCustomerCode": "3003800",
"BillingCustomerName": "SWEETWATER SURF SHOP",
"BillingState": "NC",
"BillingZip": "28480",
"InvoiceAmount": "372.72",
"InvoiceCreatedDate": "20141110",
"InvoiceItems": [
  {
    "InvoiceItemSizes": [
      {
        "InvoiceLineNumber": "1",
        "InvoicedQuantity": "3",
        "SizeCode": "L",
        "UPC": "9348282095644"
      }
    ],
    "InvoiceLineNumber": "1",
    "InvoiceNumber": "101000005",
    "InvoicedQuantity": "3",

请帮助我。

1 个答案:

答案 0 :(得分:0)

请在原始问题上看到我的观点。

这是一个样式表,可以在没有包含节点的情况下将XML转换为JSON。

此样式表也省略了最后一个逗号。如果你想保留它,你需要添加它。

  <xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 

   >


                <xsl:output method="text" />
                <xsl:variable name="nl"><xsl:text>&#xa;</xsl:text></xsl:variable>
                <xsl:variable name="tb"><xsl:text>&#x9;</xsl:text></xsl:variable>

                <xsl:template match="/*">


                    <!-- Open the root array -->
                    <xsl:text>[{</xsl:text>
                    <xsl:value-of select="$nl" />

                    <!-- Process all the child nodes of the root -->
                    <xsl:apply-templates select="*" mode="subitem" >
                        <xsl:with-param name="indent" select="$tb" />
                    </xsl:apply-templates>

                    <!-- Close the root array -->
                    <xsl:value-of select="$nl" />
                    <xsl:text>}]</xsl:text>


                </xsl:template>




                <xsl:template match="*" mode="subitem" >
                    <!-- child element at any level. The indent parameter allows for better layout of the output JSON -->
                    <xsl:param name="indent"></xsl:param>

                    <!-- newindent is used as the indent for children of this node -->
                    <xsl:variable name="newindent"><xsl:value-of select="$indent" /><xsl:value-of select="$tb"/></xsl:variable>

                    <!-- output the name of this node in quotes, ready for the content to follow -->
                    <xsl:value-of select="$indent" /><xsl:text>"</xsl:text><xsl:value-of select="name()" /><xsl:text>" :</xsl:text>

                    <!-- check if this node has children, if not, simply output the text value, otherwise outoput an array -->
                    <xsl:choose>
                        <xsl:when test=" count( ./* ) = 0 ">
                            <!-- This is a text value only -->
                                <xsl:text> "</xsl:text>

                                <!-- Make sure that any embedded quotes are escaped -->
                                <xsl:call-template name="string-replace-all">
                                    <xsl:with-param name="text" select="." />
                                    <xsl:with-param name="replace">"</xsl:with-param>
                                    <xsl:with-param name="by">\"</xsl:with-param>

                                </xsl:call-template>
                                <xsl:text>"</xsl:text>

                                <!-- check if we need a comma and a new line, not required if this is the last output value -->
                                <xsl:if test=" position() != last() ">
                                    <xsl:text>,</xsl:text>
                                    <xsl:value-of select="$nl" />
                                </xsl:if>
                        </xsl:when>
                        <xsl:otherwise>
                            <!-- This node has children, so we need to process them as an array -->

                                <!-- Array opening -->
                                <xsl:text>[</xsl:text><xsl:value-of select="$nl" />
                                <xsl:value-of select="$newindent" /><xsl:text>{</xsl:text><xsl:value-of select="$nl" />

                                    <!-- Process all the elements in the array (recursive call to this template) -->
                                    <xsl:apply-templates select="*" mode="subitem" >
                                        <xsl:with-param name="indent"><xsl:value-of select="$newindent" /></xsl:with-param>
                                    </xsl:apply-templates>

                                <!-- Close the array -->
                                <xsl:value-of select="$nl" /><xsl:value-of select="$newindent" /><xsl:text>}</xsl:text>
                                <xsl:value-of select="$nl" /><xsl:value-of select="$indent" /><xsl:text>]</xsl:text>

                                <!-- If this is not the last node then we need a comma and line feed -->
                                <xsl:if test=" position() != last() ">
                                    <xsl:text>,</xsl:text>
                                    <xsl:value-of select="$nl" />
                                </xsl:if>

                        </xsl:otherwise>

                    </xsl:choose>

                </xsl:template>


                <xsl:template name="string-replace-all">
                <!-- This code provided thanks to @codesling on stackoverflow -->
                  <xsl:param name="text" />
                  <xsl:param name="replace" />
                  <xsl:param name="by" />
                  <xsl:choose>
                    <xsl:when test="contains($text, $replace)">
                      <xsl:value-of select="substring-before($text,$replace)" />
                      <xsl:value-of select="$by" />
                      <xsl:call-template name="string-replace-all">
                        <xsl:with-param name="text"
                        select="substring-after($text,$replace)" />
                        <xsl:with-param name="replace" select="$replace" />
                        <xsl:with-param name="by" select="$by" />
                      </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:value-of select="$text" />
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:template>

    </xsl:stylesheet>

使用(更正的)XML,输出为:

 [{
    "BillingAddress1" : "10 N LUMINA AVE",
    "BillingAddress2" : "",
    "BillingCity" : "WRIGHTSVILLE BEACH",
    "BillingCountry" : "US",
    "BillingCustomerCode" : "3003800",
    "BillingCustomerName" : "SWEETWATER SURF SHOP",
    "BillingState" : "NC",
    "BillingZip" : "28480",
    "InvoiceAmount" : "372.72",
    "InvoiceCreatedDate" : "20141110",
    "InvoiceItems" :[
        {
        "InvoiceItemSizes" :[
            {
            "InvoiceLineNumber" : "1",
            "InvoicedQuantity" : "3",
            "SizeCode" : "L",
            "UPC" : "9348282095644"
            }
        ],
        "InvoiceLineNumber" : "1",
        "InvoiceNumber" : "101000005"
        }
    ]
}]