我有以下 XML:
<DocumentElement>
<Sheet1>
<FIELD_1>HD</FIELD_1>
<FIELD_2>2024</FIELD_2>
<FIELD_3>90655</FIELD_3>
<FIELD_13>667</FIELD_13>
</Sheet1>
<Sheet1>
<FIELD_1>DT</FIELD_1>
<FIELD_2>496</FIELD_2>
<FIELD_13>0339618701316335</FIELD_13>
<FIELD_22>DMax</FIELD_22>
<FIELD_30>8.41</FIELD_30>
<FIELD_65>0.16</FIELD_65>
</Sheet1>
<Sheet1>
<FIELD_1>DT</FIELD_1>
<FIELD_2>496</FIELD_2>
<FIELD_13>0339618701316335</FIELD_13>
<FIELD_22>Sign</FIELD_22>
<FIELD_30>2.50</FIELD_30>
</Sheet1>
</DocumentElement>
以下样式表正在创建以下 XML:
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl='urn:schemas-microsoft-com:xslt' xmlns:var='urn:var' xmlns:user='urn:user' exclude-result-prefixes='msxsl var user' version='1.0'>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/DocumentElement">
<DocumentElement>
<xsl:choose>
<xsl:when test="normalize-space(/DocumentElement/Sheet1[1]/FIELD_1) = 'HD' and normalize-space(/DocumentElement/Sheet1[2]/FIELD_1) = 'DT'">
<xsl:apply-templates select="Sheet1[normalize-space(FIELD_1) = 'HD' and normalize-space(FIELD_2) != 'CusId' and normalize-space(FIELD_2) != 'CusID']" />
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="Sheet1[number(FIELD_2) = FIELD_2 and normalize-space(FIELD_1) != 'DT']" />
</xsl:otherwise>
</xsl:choose>
</DocumentElement>
</xsl:template>
<xsl:template priority="1" match="Sheet1[normalize-space(FIELD_1) = 'HD']">
<Invoice>
<Ships>
<xsl:variable name="prevC" select="count(preceding-sibling::*[normalize-space(FIELD_1) = 'DT' and FIELD_2 != 'CustomerId' and FIELD_2 != 'TrackingNbr'])"/>
<xsl:variable name="newC" select="count(following-sibling::*[normalize-space(FIELD_1) = 'HD'][1]/preceding-sibling::*[normalize-space(FIELD_1) = 'DT' and FIELD_2 != 'CustomerId' and FIELD_2 != 'TrackingNbr'])"/>
<xsl:variable name="pos" select="count(following-sibling::*[ normalize-space(FIELD_1) = 'HD'][1])" />
<xsl:apply-templates select="following-sibling::*[normalize-space(FIELD_1) = 'DT'][position() < ($newC - $prevC + 1) or $pos = 0]" >
<xsl:with-param name="data" select="FIELD_3" />
</xsl:apply-templates>
</Ships>
</Invoice>
</xsl:template>
<xsl:template priority="1" match="Sheet1[normalize-space(FIELD_1) = 'DT']" >
<xsl:param name="scac"/>
<Ship>
<Lines>
<Line>
<xsl:attribute name="ReferenceNumber" >
<xsl:value-of select="normalize-space(FIELD_13)"/>
</xsl:attribute>
<LineCharge >
<xsl:attribute name="Charge" >
<xsl:choose>
<xsl:when test="normalize-space(FIELD_22) = 'Sign'">
<xsl:value-of select="'TS5'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'TS0'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="Amount" >
<xsl:value-of select="format-number(translate(FIELD_30,'$,()',''),'###0.00')"/>
</xsl:attribute>
</LineCharge>
</Line>
</Lines>
</Ship>
</xsl:template>
</xsl:stylesheet>
XML 输出:
<DocumentElement>
<Invoice>
<Ships>
<Ship>
<Lines>
<Line ReferenceNumber="0339618701316335">
<LineCharge Charge="TS0" Amount="8.41"/>
<LineCharge Charge="TS2" Amount="0.16"/>
</Line>
</Lines>
</Ship>
<Ship>
<Lines>
<Line ReferenceNumber="0339618701316335">
<LineCharge Charge="TS0" Amount="2.50"/>
</Line>
</Lines>
</Ship>
</Ships>
</Invoice>
</DocumentElement>
第一个目标:当FIELD_13中有多个具有相同值的Sheet1元素时,创建一个Ship元素。在上面的代码中添加了以下 if 语句,以防止第二个 Ship 元素被捕获:
<xsl:if test="not(preceding-sibling::*[normalize-space(FIELD_1) = 'DT' and FIELD_13 = current()/FIELD_13])">
NEW OUTPUT 仅显示一个 Ship 元素,这是正确的:
<DocumentElement>
<Invoice>
<Ships>
<Ship>
<Lines>
<Line ReferenceNumber="0339618701316335">
<LineCharge Charge="TS0" Amount="8.41"/>
</Line>
</Lines>
</Ship>
</Ships>
</Invoice>
</DocumentElement>
新问题是第二个 LineCharge 元素现在被跳过。
<LineCharge Charge="TS0" Amount="2.50"/>
我仍然需要嵌套在第二个 Ship 元素中的第二个 LineCharge 元素,但这一次,作为第一个 Ship 元素中的子元素,如下所示:
<DocumentElement>
<Invoice>
<Ships>
<Ship>
<Lines>
<Line ReferenceNumber="0339618701316335">
<LineCharge Charge="TS0" Amount="8.41"/>
<LineCharge Charge="TS5" Amount="2.50"/>
</Line>
</Lines>
</Ship>
</Ships>
</Invoice>
</DocumentElement>
如何实现最终的 XML?
非常感谢您对此提供的任何帮助。
以下是慕尼黑分组的示例,可以帮助您入门:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="key1" match="Sheet1[FIELD_1='DT']" use="FIELD_13"/>
<xsl:template match="/DocumentElement">
<DocumentElement>
<Invoice>
<Ships>
<!-- group by FIELD_13 -->
<xsl:for-each select="Sheet1[FIELD_1='DT'][generate-id()=generate-id(key('key1', FIELD_13)[1])]">
<Ship>
<Lines>
<Line ReferenceNumber="{FIELD_13}">
<!-- process current group -->
<xsl:for-each select="key('key1', FIELD_13)">
<LineCharge Charge="" Amount="{FIELD_30}"/>
</xsl:for-each>
</Line>
</Lines>
</Ship>
</xsl:for-each>
</Ships>
</Invoice>
</DocumentElement>
</xsl:template>
</xsl:stylesheet>
XML 输入:
<DocumentElement>
<Sheet1>
<FIELD_1>HD</FIELD_1>
<FIELD_13>100</FIELD_13>
</Sheet1>
<Sheet1>
<FIELD_1>DT</FIELD_1>
<FIELD_13>101</FIELD_13>
<FIELD_30>8.41</FIELD_30>
</Sheet1>
<Sheet1>
<FIELD_1>DT</FIELD_1>
<FIELD_13>101</FIELD_13>
<FIELD_30>2.50</FIELD_30>
</Sheet1>
<Sheet1>
<FIELD_1>DT</FIELD_1>
<FIELD_13>102</FIELD_13>
<FIELD_30>5.62</FIELD_30>
</Sheet1>
<Sheet1>
<FIELD_1>DT</FIELD_1>
<FIELD_13>103</FIELD_13>
<FIELD_30>4.59</FIELD_30>
</Sheet1>
<Sheet1>
<FIELD_1>DT</FIELD_1>
<FIELD_13>103</FIELD_13>
<FIELD_30>9.97</FIELD_30>
</Sheet1>
</DocumentElement>
您将得到:
<?xml version="1.0"?>
<DocumentElement>
<Invoice>
<Ships>
<Ship>
<Lines>
<Line ReferenceNumber="101">
<LineCharge Charge="" Amount="8.41"/>
<LineCharge Charge="" Amount="2.50"/>
</Line>
</Lines>
</Ship>
<Ship>
<Lines>
<Line ReferenceNumber="102">
<LineCharge Charge="" Amount="5.62"/>
</Line>
</Lines>
</Ship>
<Ship>
<Lines>
<Line ReferenceNumber="103">
<LineCharge Charge="" Amount="4.59"/>
<LineCharge Charge="" Amount="9.97"/>
</Line>
</Lines>
</Ship>
</Ships>
</Invoice>
</DocumentElement>