如何通过位置验证值以避免在 xslt 中打印标题?

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

是 xslt 新手,我正在使用 xslt 1.0 从 xml 代码创建 PDF。

我的源数据如下。

<STATEMENT>
    <STATEMENT_AGING>
        <AGING>
            <AGING_LABEL>Current</AGING_LABEL>
            <AGING_AMOUNT>$28,927.43</AGING_AMOUNT>
        </AGING>
        <AGING>
            <AGING_LABEL>1 - 30</AGING_LABEL>
            <AGING_AMOUNT>$0.00</AGING_AMOUNT>
        </AGING>
        <AGING>
            <AGING_LABEL>31 - 60</AGING_LABEL>
            <AGING_AMOUNT>$0.00</AGING_AMOUNT>
        </AGING>
        <AGING>
            <AGING_LABEL>61 - 90</AGING_LABEL>
            <AGING_AMOUNT>$0.00</AGING_AMOUNT>
        </AGING>
        <AGING>
            <AGING_LABEL>91 - 120</AGING_LABEL>
            <AGING_AMOUNT>$0.00</AGING_AMOUNT>
        </AGING>
        <AGING>
            <AGING_LABEL>Over 120</AGING_LABEL>
            <AGING_AMOUNT>$0.00</AGING_AMOUNT>
        </AGING>
    </STATEMENT_AGING>
    <GROUP 
           ID='1'
           label=''>
        <GROUP_LABEL />
        <GROUP_NAME>SoleraStatementSection</GROUP_NAME>
        <GROUP_TYPE>LABEL</GROUP_TYPE>
        <GROUP_HIDE_FLAG>0</GROUP_HIDE_FLAG>
        <GROUP_HEADER_ROW>
            <COL 
                 headerAlign='start'
                 headerFormat='text'
                 width='2cm'>Doc. #</COL>
            <COL 
                 headerAlign='start'
                 headerFormat='text'
                 width='1cm'>Doc. Type</COL>
            <COL 
                 headerAlign='start'
                 headerFormat='text'
                 width='1cm'>Doc. Date</COL>
            <COL 
                 headerAlign='start'
                 headerFormat='text'
                 width='1cm'>Due Date</COL>
            <COL 
                 headerAlign='center'
                 headerFormat='text'
                 width='1cm'>Currency</COL>
            <COL 
                 headerAlign='end'
                 headerFormat='currency'
                 width='1cm'>Original Amount</COL>
            <COL 
                 headerAlign='end'
                 headerFormat='currency'
                 width='1cm'>Balance</COL>
            <COL 
                 headerAlign='start'
                 headerFormat='number'
                 width='1cm'>ChildAccount</COL>
        </GROUP_HEADER_ROW>
        <GROUP_DATA_ROW>
            <COL>2120-000023134</COL>
            <COL>Invoice</COL>
            <COL>2024-05-13T00:23:14.205918-05:00</COL>
            <COL>2024-06-12T05:00:00.000000+00:00</COL>
            <COL>USD</COL>
            <COL>$13,247.46</COL>
            <COL>$13,247.46</COL>
            <COL>Price Acura</COL>
        </GROUP_DATA_ROW>
        <GROUP_DATA_ROW>
            <COL>2120-000023135</COL>
            <COL>Invoice</COL>
            <COL>2024-05-13T00:36:37.008144-05:00</COL>
            <COL>2024-06-12T05:00:00.000000+00:00</COL>
            <COL>USD</COL>
            <COL>$13,247.37</COL>
            <COL>$13,247.37</COL>
            <COL>Price Acura</COL>
        </GROUP_DATA_ROW>
        <GROUP_DATA_ROW>
            <COL>2120-000023136</COL>
            <COL>Invoice</COL>
            <COL>2024-05-13T00:51:32.838201-05:00</COL>
            <COL>2024-06-12T05:00:00.000000+00:00</COL>
            <COL>USD</COL>
            <COL>$2,432.60</COL>
            <COL>$2,432.60</COL>
            <COL>Price Honda</COL>
        </GROUP_DATA_ROW>
    </GROUP>
    <GROUP ID='2'
           label=''>
        <GROUP_LABEL />
        <GROUP_NAME>CreditData</GROUP_NAME>
        <GROUP_TYPE>LABEL</GROUP_TYPE>
        <GROUP_HIDE_FLAG>0</GROUP_HIDE_FLAG>
        <GROUP_HEADER_ROW>
            <COL 
                 headerAlign='start'
                 headerFormat='text'
                 width='0cm'>Credit #</COL>
            <COL 
                 headerAlign='start'
                 headerFormat='text'
                 width='0cm'>Credit Type</COL>
            <COL 
                 headerAlign='start'
                 headerFormat='text'
                 width='0cm'>Credit Date</COL>
            <COL 
                 headerAlign='center'
                 headerFormat='text'
                 width='0cm'>Currency</COL>
            <COL 
                 headerAlign='end'
                 headerFormat='currency'
                 width='0cm'>Credit Amount</COL>
            <COL 
                 headerAlign='end'
                 headerFormat='currency'
                 width='0cm'>Unallocated Amnt</COL>
            <COL 
                 headerAlign='start'
                 headerFormat='text'
                 width='0cm'>ChildAccount</COL>
        </GROUP_HEADER_ROW>
    </GROUP>
    <GROUP ID='3'
           label=''>
        <GROUP_LABEL />
        <GROUP_NAME>PaymentSection</GROUP_NAME>
        <GROUP_TYPE>LABEL</GROUP_TYPE>
        <GROUP_HIDE_FLAG>0</GROUP_HIDE_FLAG>
        <GROUP_HEADER_ROW>
            <COL 
                 headerAlign='start'
                 headerFormat='text'
                 width='0cm'>Payment #</COL>
            <COL 
                 headerAlign='start'
                 headerFormat='text'
                 width='0cm'>Payment Type</COL>
            <COL 
                 headerAlign='start'
                 headerFormat='text'
                 width='0cm'>Payment Date</COL>
            <COL 
                 headerAlign='center'
                 headerFormat='text'
                 width='0cm'>Currency</COL>
            <COL 
                 headerAlign='end'
                 headerFormat='currency'
                 width='0cm'>Payment Amount</COL>
            <COL 
                 headerAlign='end'
                 headerFormat='currency'
                 width='0cm'>Unallocated Amnt</COL>
            <COL 
                 headerAlign='start'
                 headerFormat='text'
                 width='0cm'>ChildAccount</COL>
        </GROUP_HEADER_ROW>
    </GROUP>
</STATEMENT>

问题是,在 GROUPID 1 中,我尝试按 custName 或 col[8] 对数据进行分组,但我想在每次 custName 更改时打印标题。我尝试将值存储到变量中,但一旦循环再次出现,该值就会丢失,因此我尝试使用 IF 进行评估时不起作用。

有谁知道我该如何管理这个问题,因为我看到了很多使用 diff 方法的答案,但我不太理解所有这些答案,因为我的源 xml 有“通用”标签而不是真实的标签名称。

PS。我尝试了选择和 if 条件,但它们都不起作用。

    <xsl:template name= "DetailSectionG1">
        <fo:block space-before="8mm" font-weight="bold" color="{$blue-color}" keep-together.within-page="always" keep-with-next="always">
            <fo:table width="100%" border-collapse="collapse" table-layout="fixed">
                <fo:table-column column-width="{$left-margin}"/>
                <fo:table-column column-width="proportional-column-width(1)"/>
                <fo:table-column column-width="{$right-margin}"/>
                <fo:table-body>
                    <fo:table-row>
                        <fo:table-cell>
                            <fo:block/>
                        </fo:table-cell>
                        <fo:table-cell>
                            <fo:block font-size="{$large-font-size}" padding-top="3 * {$padding}" padding-bottom="{$padding}">
                                Statement Details
                            </fo:block>
                        </fo:table-cell>
                    </fo:table-row>
                </fo:table-body>
            </fo:table>
        </fo:block>
        <xsl:choose>
            <xsl:when test="GROUP[@ID=1]/GROUP_DATA_ROW/COL[1] !=''">
                <fo:block>
                    <fo:table width="100%" border-collapse="collapse" table-layout="fixed">
                        <fo:table-column column-width="{$data-left-margin}"/>
                        <fo:table-column column-width="30mm"/>
                        <fo:table-column column-width="25mm"/>
                        <fo:table-column column-width="25mm"/>
                        <fo:table-column column-width="25mm"/>
                        <fo:table-column column-width="22mm"/>
                        <fo:table-column column-width="27mm"/>
                        <fo:table-column column-width="25mm"/>
                        <fo:table-column column-width="{$data-right-margin}"/>
                        <xsl:for-each select="/STATEMENT/GROUP[@ID=1]/GROUP_DATA_ROW[generate-id(.)=generate-id(key('groupDataRow', concat(COL[position() = 8],'+',COL[position() = 1])))]">
                            <xsl:variable name="vGroup" select="key('kAllFields', concat(COL[position() = 8],'+',COL[position() = 1]))"/>
                            <fo:table-body>
                                <xsl:choose>
                                    <xsl:when test="custName != COL[position() = 8] or position() = 1">
                                        <fo:table-row>
                                            <fo:table-cell>
                                                <fo:block/>
                                            </fo:table-cell>
                                            <fo:table-cell>
                                                <fo:block font-weight="bold" color="{$blue-color}" keep-together.within-page="always" keep-with-next="always" padding-bottom="{$padding}"/>
                                                    <!--xsl:value-of select="COL[position() = 8]"/-->
                                                <!--/fo:block-->
                                            </fo:table-cell>
                                        </fo:table-row>
                                        <fo:table-row>
                                            <fo:table-cell>
                                                <fo:block/>
                                            </fo:table-cell>
                                            <xsl:call-template name="HeaderCell">
                                                <xsl:with-param name="position">1</xsl:with-param>
                                                <xsl:with-param name="color" select="$blue-color"/>
                                            </xsl:call-template>
                                            <xsl:call-template name="HeaderCell">
                                                <xsl:with-param name="position">2</xsl:with-param>
                                                <xsl:with-param name="color" select="$blue-color"/>
                                            </xsl:call-template>
                                            <xsl:call-template name="HeaderCell">
                                                <xsl:with-param name="position">3</xsl:with-param>
                                                <xsl:with-param name="color" select="$blue-color"/>
                                            </xsl:call-template>
                                            <xsl:call-template name="HeaderCell">
                                                <xsl:with-param name="position">4</xsl:with-param>
                                                <xsl:with-param name="color" select="$blue-color"/>
                                            </xsl:call-template>
                                            <xsl:call-template name="HeaderCell">
                                                <xsl:with-param name="position">5</xsl:with-param>
                                                <xsl:with-param name="color" select="$blue-color"/>
                                            </xsl:call-template>
                                            <xsl:call-template name="HeaderCell">
                                                <xsl:with-param name="position">6</xsl:with-param>
                                                <xsl:with-param name="color" select="$blue-color"/>
                                            </xsl:call-template>
                                            <xsl:call-template name="HeaderCell">
                                                <xsl:with-param name="position">7</xsl:with-param>
                                                <xsl:with-param name="color" select="$blue-color"/>
                                            </xsl:call-template>
                                        </fo:table-row>
                                    </xsl:when>
                                    <xsl:otherwise/>
                                </xsl:choose>
                                <!--xsl:if test="{$acctName} != COL[position() = 8] or position() = 1"> </xsl:if-->
                                <fo:table-row>
                                    <fo:table-cell>
                                        <fo:block/>
                                    </fo:table-cell>
                                    <xsl:call-template name="Cell">
                                        <xsl:with-param name="position">1</xsl:with-param>
                                    </xsl:call-template>
                                    <xsl:call-template name="Cell">
                                        <xsl:with-param name="position">2</xsl:with-param>
                                    </xsl:call-template>
                                    <fo:table-cell>
                                        <fo:block color="{$base-color}" padding-bottom="{$small-padding}">
                                            <xsl:attribute name="end-indent">1mm</xsl:attribute>
                                            <xsl:attribute name="text-align">
                                                <xsl:value-of select="../GROUP_HEADER_ROW[1]/COL[position() = 3]/@headerAlign"/>
                                            </xsl:attribute>
                                            <xsl:call-template name="getDate">
                                                <xsl:with-param name="value" select="COL[position()=3]"/>
                                            </xsl:call-template>
                                        </fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block color="{$base-color}" padding-bottom="{$small-padding}">
                                            <xsl:attribute name="end-indent">1mm</xsl:attribute>
                                            <xsl:attribute name="text-align">
                                                <xsl:value-of select="../GROUP_HEADER_ROW[1]/COL[position() = 4]/@headerAlign"/>
                                            </xsl:attribute>
                                            <xsl:call-template name="getDate">
                                                <xsl:with-param name="value" select="COL[position()=4]"/>
                                            </xsl:call-template>
                                        </fo:block>
                                    </fo:table-cell>
                                    <xsl:call-template name="Cell">
                                        <xsl:with-param name="position">5</xsl:with-param>
                                    </xsl:call-template>
                                    <xsl:call-template name="Cell">
                                        <xsl:with-param name="position">6</xsl:with-param>
                                    </xsl:call-template>
                                    <xsl:call-template name="Cell">
                                        <xsl:with-param name="position">7</xsl:with-param>
                                    </xsl:call-template>
                                </fo:table-row>
                                <xsl:variable name="custName">
                                    <xsl:value-of select="COL[position() = 8]"/>
                                </xsl:variable>
                            </fo:table-body>
                        </xsl:for-each>
                    </fo:table>
                </fo:block>
            </xsl:when>
            <xsl:otherwise>
                <fo:block keep-together.within-page="always" keep-with-next="always">
                    <fo:table width="100%" border-collapse="collapse" table-layout="fixed">
                        <fo:table-column column-width="{$left-margin}"/>
                        <fo:table-column column-width="proportional-column-width(1)"/>
                        <fo:table-column column-width="{$right-margin}"/>
                        <fo:table-body>
                            <fo:table-row>
                                <fo:table-cell>
                                    <fo:block/>
                                </fo:table-cell>
                                <fo:table-cell>
                                    <fo:block color="{$base-color}" padding-bottom="{$small-padding}" end-indent="1mm">
                                        No invoices to display
                                    </fo:block>
                                </fo:table-cell>
                            </fo:table-row>
                        </fo:table-body>
                    </fo:table>
                </fo:block>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

我期望的 PDF 就是这个。

[期望输出] (https://i.sstatic.net/GPAPwxHQ.png)

目前我尝试的验证不起作用,并且 acctName 和标头表仅显示一次。

电流输出

validation variables xslt grouping
1个回答
0
投票

您似乎在分组方面遇到了困难,请注意,在 XSLT 2 或更高版本中,分组要容易得多,您可以这样做

  <xsl:template match="GROUP[@ID = 1]">
    <xsl:for-each-group select="GROUP_DATA_ROW" group-by="COL[8]">
      <group key="{current-grouping-key()}">
        <xsl:sequence select="current-group()"/>
      </group>
    </xsl:for-each-group>
  </xsl:template>

并获得例如

<group key="Price Acura">
   <GROUP_DATA_ROW>
      <COL>2120-000023134</COL>
      <COL>Invoice</COL>
      <COL>2024-05-13T00:23:14.205918-05:00</COL>
      <COL>2024-06-12T05:00:00.000000+00:00</COL>
      <COL>USD</COL>
      <COL>$13,247.46</COL>
      <COL>$13,247.46</COL>
      <COL>Price Acura</COL>
   </GROUP_DATA_ROW>
   <GROUP_DATA_ROW>
      <COL>2120-000023135</COL>
      <COL>Invoice</COL>
      <COL>2024-05-13T00:36:37.008144-05:00</COL>
      <COL>2024-06-12T05:00:00.000000+00:00</COL>
      <COL>USD</COL>
      <COL>$13,247.37</COL>
      <COL>$13,247.37</COL>
      <COL>Price Acura</COL>
   </GROUP_DATA_ROW>
</group>
<group key="Price Honda">
   <GROUP_DATA_ROW>
      <COL>2120-000023136</COL>
      <COL>Invoice</COL>
      <COL>2024-05-13T00:51:32.838201-05:00</COL>
      <COL>2024-06-12T05:00:00.000000+00:00</COL>
      <COL>USD</COL>
      <COL>$2,432.60</COL>
      <COL>$2,432.60</COL>
      <COL>Price Honda</COL>
   </GROUP_DATA_ROW>
</group>

因此您可以轻松地拥有两个组和每个组的正确数据,我没有尝试输出想要的 XSL-FO,但是一旦您解决了分组问题就应该很容易。

请注意,XSLT 3(XSLT 的当前版本)在多种平台、浏览器 (https://www.saxonica.com/download/javascript.xml) 和 Node.js () 中受支持https://www.npmjs.com/package/saxon-js)您可以使用 SaxonJS 2(2.6 是当前版本),对于 Java,您可以在 Maven 上找到 Saxon HE https://mvnrepository.com/artifact/ net.sf.saxon/Saxon-HE 或在 Github 上,对于 Python,有 SaxonCHE (https://pypi.org/project/saxonche/),对于 .NET,有 Saxon .NET HE (https:/ /www.nuget.org/packages/Saxon-HEhttps://www.nuget.org/packages/SaxonHE12s9apiExtensions)。

尽管如此,如果您在受限环境中工作而被迫使用 XSLT 1,请使用密钥

  <xsl:key name="group" match="GROUP[@ID = 1]/GROUP_DATA_ROW" use="COL[8]"/>
  
  <xsl:template match="GROUP[@ID = 1]">
    <xsl:for-each select="GROUP_DATA_ROW[generate-id() = generate-id(key('group', COL[8])[1])]">
      <group key="{COL[8]}">
        <xsl:copy-of select="key('group', COL[8])"/>
      </group>
    </xsl:for-each>
  </xsl:template>
© www.soinside.com 2019 - 2024. All rights reserved.