XSLT 1.0 模板如何在逻辑后检索第二次出现的值以完全跳过第二次出现

问题描述 投票:0回答:1

我有以下 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() &lt; ($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?

非常感谢您对此提供的任何帮助。

xslt
1个回答
0
投票

以下是慕尼黑分组的示例,可以帮助您入门:

<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>
© www.soinside.com 2019 - 2024. All rights reserved.