我是XSLT的新手。使用XSLT将XML转换为JSON时遇到问题。
XML输入
<ArrayOfApiInvoiceReport>
<ApiInvoiceReport>
<BillingAddress1>9055 LOCUST ST STE B10</BillingAddress1>
<BillingAddress2/>
<BillingCity>ELK GROVE</BillingCity>
<BillingCountry>US</BillingCountry>
<InvoiceItems>
<InvoiceItemSizes>
<InvoiceLineNumber>1</InvoiceLineNumber>
<InvoicedQuantity>2</InvoicedQuantity>
</InvoiceItemSizes>
<InvoiceLineNumber>1</InvoiceLineNumber>
<InvoiceNumber>101000001</InvoiceNumber>
</InvoiceItems>
<InvoiceItems>
<InvoiceItemSizes>
<InvoiceLineNumber>2</InvoiceLineNumber>
<InvoicedQuantity>2</InvoicedQuantity>
</InvoiceItemSizes>
<InvoiceLineNumber>2</InvoiceLineNumber>
<InvoiceNumber>101000001</InvoiceNumber>
</InvoiceItems>
<InvoiceNumber>101000001</InvoiceNumber>
<InvoiceSentDate>20141109</InvoiceSentDate>
<InvoiceStatus>95</InvoiceStatus>
</ApiInvoiceReport>
<ApiInvoiceReport>
<BillingAddress1>9055 LOCUST ST STE B10</BillingAddress1>
<BillingAddress2/>
<BillingCity>ELK GROVE</BillingCity>
<BillingCountry>US</BillingCountry>
<InvoiceItems>
<InvoiceItemSizes>
<InvoiceLineNumber>1</InvoiceLineNumber>
<InvoicedQuantity>2</InvoicedQuantity>
</InvoiceItemSizes>
<InvoiceLineNumber>1</InvoiceLineNumber>
<InvoiceNumber>101000002</InvoiceNumber>
</InvoiceItems>
<InvoiceNumber>101000002</InvoiceNumber>
<InvoiceSentDate>20141109</InvoiceSentDate>
<InvoiceStatus>95</InvoiceStatus>
</ApiInvoiceReport>
</ArrayOfApiInvoiceReport>
输出JSON
[{
"ApiInvoiceReport": [
{
"BillingAddress1": "9055 LOCUST ST STE B10",
"BillingAddress2": "",
"BillingCity": "ELK GROVE",
"BillingCountry": "US",
"InvoiceItems": [
{
"InvoiceItemSizes": [
{
"InvoiceLineNumber": "1",
"InvoicedQuantity": "2"
}
],
"InvoiceLineNumber": "1",
"InvoiceNumber": "101000001"
},
{
"InvoiceItemSizes": [
{
"InvoiceLineNumber": "2",
"InvoicedQuantity": "2"
}
],
"InvoiceLineNumber": "2",
"InvoiceNumber": "101000001"
}
],
"InvoiceNumber": "101000001",
"InvoiceSentDate": "20141109",
"InvoiceStatus": "95"
},
{
"BillingAddress1": "9055 LOCUST ST STE B10",
"BillingAddress2": "",
"BillingCity": "ELK GROVE",
"BillingCountry": "US",
"InvoiceItems": [
{
"InvoiceItemSizes": [
{
"InvoiceLineNumber": "1",
"InvoicedQuantity": "2"
}
],
"InvoiceLineNumber": "1",
"InvoiceNumber": "101000002"
}
],
"InvoiceNumber": "101000002",
"InvoiceSentDate": "20141109",
"InvoiceStatus": "95"
}
] }]
使用XSLT
<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="utf-8" method="text" omit-xml-declaration="yes"/>
<xsl:variable name="nl">
<xsl:text/>
</xsl:variable>
<xsl:variable name="tb">
<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 mode="detect" select="*">
<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="detect">
<xsl:choose>
<xsl:when test="name(preceding-sibling::*[1]) = name(current()) and name(following-sibling::*[1]) != name(current())">
<xsl:apply-templates mode="obj-content" select="."/>
<xsl:text>]</xsl:text>
<xsl:if test="count(following-sibling::*[name() != name(current())]) > 0">, </xsl:if>
</xsl:when>
<xsl:when test="name(preceding-sibling::*[1]) = name(current())">
<xsl:apply-templates mode="obj-content" select="."/>
<xsl:if test="name(following-sibling::*) = name(current())">, </xsl:if>
</xsl:when>
<xsl:when test="following-sibling::*[1][name() = name(current())]">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>" : [</xsl:text>
<xsl:apply-templates mode="obj-content" select="."/>
<xsl:text>, </xsl:text>
</xsl:when>
<xsl:when test="count(./child::*) > 0 or count(@*) > 0">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>" : [<xsl:apply-templates
mode="obj-content" select="."/>
<xsl:if test="count(following-sibling::*) > 0">], </xsl:if>
</xsl:when>
<xsl:when test="count(./child::*) = 0">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>" : "<xsl:apply-templates select="."/>
<xsl:text>"</xsl:text>
<xsl:if test="count(following-sibling::*) > 0">, </xsl:if>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="*" mode="obj-content">
<xsl:text>{</xsl:text>
<xsl:apply-templates mode="attr" select="@*"/>
<xsl:if test="count(@*) > 0 and (count(child::*) > 0 or text())">, </xsl:if>
<xsl:apply-templates mode="detect" select="./*"/>
<xsl:if test="count(child::*) = 0 and text() and not(@*)">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>" : "<xsl:value-of select="text()"/>
<xsl:text>"</xsl:text>
</xsl:if>
<xsl:if test="count(child::*) = 0 and text() and @*">
<xsl:text>: "</xsl:text>
<xsl:value-of select="text()"/>
<xsl:text>"</xsl:text>
</xsl:if>
<xsl:text>}</xsl:text>
<xsl:if test="position() < last()">, </xsl:if>
</xsl:template>
<xsl:template match="@*" mode="attr">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>" : "<xsl:value-of select="."/>
<xsl:text>"</xsl:text>
<xsl:if test="position() < last()">,</xsl:if>
</xsl:template>
<xsl:template match="node/@TEXT | text()" name="removeBreaks">
<xsl:param name="pText" select="normalize-space(.)"/>
<xsl:choose>
<xsl:when test="not(contains($pText, '
'))">
<xsl:copy-of select="$pText"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(substring-before($pText, '
'), ' ')"/>
<xsl:call-template name="removeBreaks">
<xsl:with-param name="pText" select="substring-after($pText, '
')"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
需要输出
[
{
"BillingAddress1": "9055 LOCUST ST STE B10",
"BillingAddress2": "",
"BillingCity": "ELK GROVE",
"InvoiceItems": [
{
"InvoiceItemSizes": [
{
"InvoiceLineNumber": "1",
"InvoicedQuantity": "2",
"SizeCode": "1SZ",
"UPC": "9343744951476"
}
],
"InvoiceLineNumber": "1",
"InvoiceNumber": "101000001",
"InvoicedQuantity": "2",
"ProductInvoicedPrice": "100.00",
"ProductName": "K38 TIDEMASTER SILICONE",
"ProductNumber": "A1103BLK1SZ"
},
{
"InvoiceItemSizes": [
{
"InvoiceLineNumber": "2",
"InvoicedQuantity": "2",
"SizeCode": "1SZ",
"UPC": "9343744054450"
}
],
"InvoiceLineNumber": "2",
"InvoiceNumber": "101000001",
"InvoicedQuantity": "2",
"ProductInvoicedPrice": "40.00",
"ProductName": "PIVOT PU",
"ProductNumber": "A2410BLK1SZ"
}
],
"ShippingAddress1": "9055 LOCUST ST STE B10",
"ShippingAddress2": "",
"ShippingCity": "ELK GROVE"
},
{
"BillingAddress1": "9055 LOCUST ST STE B10",
"BillingAddress2": "",
"BillingCity": "ELK GROVE",
"InvoiceItems": [
{
"InvoiceItemSizes": [
{
"InvoiceLineNumber": "1",
"InvoicedQuantity": "2",
"SizeCode": "1SZ",
"UPC": "9348282068914"
}
],
"InvoiceLineNumber": "1",
"InvoiceNumber": "101000002",
"InvoicedQuantity": "2",
"ProductInvoicedPrice": "45.00",
"ProductName": "CANDY DIGITAL",
"ProductNumber": "A2466GWHI1SZ"
}
],
"ShippingAddress1": "9055 LOCUST ST STE B10",
"ShippingAddress2": "",
"ShippingCity": "ELK GROVE"
}
]`
从JSON输出中我们只需要删除ApiInvoiceReport标记。 我试图解决这个问题但我做不到。
答案 0 :(得分:0)
一个解决方案可能是(不是最优雅的)。改变下一个:
<xsl:when test="following-sibling::*[1][name() = name(current())]">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>" : [</xsl:text>
<xsl:apply-templates mode="obj-content" select="."/>
<xsl:text>, </xsl:text>
</xsl:when>
要:
<xsl:when test="following-sibling::*[1][name() = name(current())]">
<xsl:choose>
<xsl:when test="local-name(current()) = 'ApiInvoiceReport'">
<xsl:apply-templates mode="detect" select="*"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>" : [</xsl:text>
<xsl:apply-templates mode="obj-content" select="."/>
<xsl:text>, </xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:when>