Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xslt 嵌套在for each循环中的每个(-group)的XSL_Xslt_Xslt 2.0 - Fatal编程技术网

Xslt 嵌套在for each循环中的每个(-group)的XSL

Xslt 嵌套在for each循环中的每个(-group)的XSL,xslt,xslt-2.0,Xslt,Xslt 2.0,我们的目标是打印发票行,首先按发票服务类型分组,然后按工作描述和员工姓名分组,方式如下: 咨询 实际工作 Gummo-2014-03-03 泽波-2014-02-24 哈波-2014-03-07 讽刺的话 格鲁乔-2014-02-24 竖琴演奏 哈波-2014-02-28 发生的费用 雪茄 我们从一个结构比较复杂的xml文件中提取这些数据,即丹麦国家OIOUBL标准: <Invoice> (...) <cac:InvoiceLine> <cbc:ID&g

我们的目标是打印发票行,首先按发票服务类型分组,然后按工作描述和员工姓名分组,方式如下:

咨询 实际工作 Gummo-2014-03-03 泽波-2014-02-24 哈波-2014-03-07

讽刺的话 格鲁乔-2014-02-24

竖琴演奏 哈波-2014-02-28

发生的费用 雪茄

我们从一个结构比较复杂的xml文件中提取这些数据,即丹麦国家OIOUBL标准:

<Invoice>

(...)

<cac:InvoiceLine>
    <cbc:ID>1</cbc:ID>
    <cbc:Note>Bla bla</cbc:Note>
    <cbc:InvoicedQuantity unitCode="EA">1.2500</cbc:InvoicedQuantity>
    <cbc:LineExtensionAmount currencyID="DKK">1395.0000</cbc:LineExtensionAmount>
    <cac:Delivery>
      <cbc:ActualDeliveryDate>2014-02-24</cbc:ActualDeliveryDate>
    </cac:Delivery>
    <cac:TaxTotal>
      <cbc:TaxAmount currencyID="DKK">348.75</cbc:TaxAmount>
      <cac:TaxSubtotal>
        <cbc:TaxableAmount currencyID="DKK">1395.00</cbc:TaxableAmount>
        <cbc:TaxAmount currencyID="DKK">348.75</cbc:TaxAmount>
        <cac:TaxCategory>
          <cbc:ID schemeAgencyID="320" schemeID="urn:oioubl:id:taxcategoryid-1.1">StandardRated</cbc:ID>
          <cbc:Percent>25.00</cbc:Percent>
          <cac:TaxScheme>
            <cbc:ID schemeAgencyID="320" schemeID="urn:oioubl:id:taxschemeid-1.1">63</cbc:ID>
            <cbc:Name>Moms</cbc:Name>
          </cac:TaxScheme>
        </cac:TaxCategory>
      </cac:TaxSubtotal>
    </cac:TaxTotal>
    <cac:Item>
      <cbc:Description>Snide Remarks</cbc:Description>
      <cbc:Name>CONSULTANCY</cbc:Name>
      <cac:SellersItemIdentification>
        <cbc:ID schemeAgencyID="9" schemeID="foo">Groucho</cbc:ID>
        <cbc:ExtendedID>Timer</cbc:ExtendedID>
      </cac:SellersItemIdentification>
      <cac:StandardItemIdentification>
        <cbc:ID schemeAgencyID="9" schemeID="foo">2014-02-24</cbc:ID>
      </cac:StandardItemIdentification>
      <cac:AdditionalItemIdentification>
        <cbc:ID schemeAgencyID="9" schemeID="foo">10000</cbc:ID>
      </cac:AdditionalItemIdentification>
    </cac:Item>
    <cac:Price>
      <cbc:PriceAmount currencyID="DKK">1116.0000</cbc:PriceAmount>
      <cbc:BaseQuantity unitCode="EA">1</cbc:BaseQuantity>
    </cac:Price>
  </cac:InvoiceLine>

(...)

  <cac:InvoiceLine>
    <cbc:ID>6</cbc:ID>
    <cbc:InvoicedQuantity unitCode="EA">1.0000</cbc:InvoicedQuantity>
    <cbc:LineExtensionAmount currencyID="DKK">1116.0000</cbc:LineExtensionAmount>
    <cac:Delivery>
      <cbc:ActualDeliveryDate>2014-03-06</cbc:ActualDeliveryDate>
    </cac:Delivery>
    <cac:TaxTotal>
      <cbc:TaxAmount currencyID="DKK">279.00</cbc:TaxAmount>
      <cac:TaxSubtotal>
        <cbc:TaxableAmount currencyID="DKK">1116.00</cbc:TaxableAmount>
        <cbc:TaxAmount currencyID="DKK">279.00</cbc:TaxAmount>
        <cac:TaxCategory>
          <cbc:ID schemeAgencyID="320" schemeID="urn:oioubl:id:taxcategoryid-1.1">StandardRated</cbc:ID>
          <cbc:Percent>25.00</cbc:Percent>
          <cac:TaxScheme>
            <cbc:ID schemeAgencyID="320" schemeID="urn:oioubl:id:taxschemeid-1.1">63</cbc:ID>
            <cbc:Name>Moms</cbc:Name>
          </cac:TaxScheme>
        </cac:TaxCategory>
      </cac:TaxSubtotal>
    </cac:TaxTotal>
    <cac:Item>
      <cbc:Description>Cigars</cbc:Description>
      <cbc:Name>EXPENSES INCURRED</cbc:Name>
      <cac:SellersItemIdentification>
        <cbc:ID schemeAgencyID="9" schemeID="foo"></cbc:ID>
        <cbc:ExtendedID>Timer</cbc:ExtendedID>
      </cac:SellersItemIdentification>
      <cac:StandardItemIdentification>
        <cbc:ID schemeAgencyID="9" schemeID="foo">2014-03-06</cbc:ID>
      </cac:StandardItemIdentification>
      <cac:AdditionalItemIdentification>
        <cbc:ID schemeAgencyID="9" schemeID="foo">20000</cbc:ID>
      </cac:AdditionalItemIdentification>
    </cac:Item>
    <cac:Price>
      <cbc:PriceAmount currencyID="DKK">1116.0000</cbc:PriceAmount>
      <cbc:BaseQuantity unitCode="EA">1</cbc:BaseQuantity>
    </cac:Price>
  </cac:InvoiceLine>

  </Invoice>
我们从XSL样式表开始,先做一个简单的for each循环,按cac:InvoiceLine/cac:Item/cac:AdditionalItemIdentification将发票行分组咨询行标记为10000,费用行标记为20000;然后,我们需要确保每个咨询行首先按照工作描述cac:InvoiceLine/cac:Item/cbc:description进行分组。我们已经尝试了多次进一步的for-each循环、for-each-group和使用键的解决方案的迭代。然而,它们似乎都依赖于XPath问题

<xsl:choose>
<xsl:when test="$layouttype = '1'">

    <xsl:for-each select="cac:InvoiceLine/cac:Item/cac:AdditionalItemIdentification[cbc:ID='10000']">
        <!-- Invoice headline - Printed once-->
        <xsl:if test="number(position()) = 1">
            <fo:table-row margin-left="0mm" margin-right="0mm" white-space="normal">
                <!-- see if period is empty so colspan should be = 2 -->
                <xsl:choose>
                    <xsl:when test="../cac:StandardItemIdentification/cbc:ID != 'n/a'">
                        <fo:table-cell display-align="after">
                            <fo:block margin-bottom="1mm" font-weight="bold">
                                <xsl:value-of select="../cbc:Name"/>
                            </fo:block>
                        </fo:table-cell>
                    </xsl:when>
                    <xsl:otherwise>
                        <fo:table-cell number-columns-spanned="2" display-align="after">
                            <fo:block margin-bottom="1mm" font-weight="bold">
                                <xsl:value-of select="../cbc:Name"/>
                            </fo:block>
                        </fo:table-cell>
                    </xsl:otherwise>
                </xsl:choose>
            </fo:table-row>
        </xsl:if>

        <!-- the actual invoice line -->
        <!-- and this is where it gets tricky... -->

        <xsl:for-each-group select="../cbc:Description" group-by="../cbc:Description">
            <fo:table-row>
                <fo:table-cell>
                    <fo:block><xsl:value-of select="../cbc:Description"/></fo:block>
                </fo:table-cell>
            </fo:table-row>


            <xsl:for-each select="current-group()">

                <fo:table-row>
                    <fo:table-cell>

                        <fo:block>
                            <xsl:value-of select="../cac:SellersItemIdentification/cbc:ID"/>
                        </fo:block>

                    </fo:table-cell>
                </fo:table-row>

            </xsl:for-each>

        </xsl:for-each-group>

    </xsl:for-each>

    <xsl:for-each select="cac:InvoiceLine/cac:Item/cac:AdditionalItemIdentification[cbc:ID='20000']">

<!-- then the same pattern is repeated -->

最好尽可能避免重复代码。目前还不清楚你是否只会有咨询和费用,但可以放心地假设不会。我还将假设每个InvoiceLine可以有多个Item元素,尽管如果不是这样,给出的解决方案仍然有效

无论如何,您应该首先按照项目元素的AdditionalItemIdentification对项目元素进行分组。这将为您的咨询和费用创建组

<xsl:for-each-group select="cac:InvoiceLine/cac:Item" 
                    group-by="cac:AdditionalItemIdentification/cbc:ID">
<xsl:for-each-group select="current-group()[cac:SellersItemIdentification/cbc:ID != '']" 
                    group-by="cac:SellersItemIdentification/cbc:ID">
然后,只需输出名称,即可获得每个组的标题

<xsl:value-of select="cbc:Name" />
现在,在当前的Item元素组中,您需要根据描述进行分组

最后,在该组中,您仍然希望按SellerItemIdentification对项目进行分组,尽管您可能需要额外检查,因为在发生费用的情况下,并非所有项目元素都有这些检查

<xsl:for-each-group select="cac:InvoiceLine/cac:Item" 
                    group-by="cac:AdditionalItemIdentification/cbc:ID">
<xsl:for-each-group select="current-group()[cac:SellersItemIdentification/cbc:ID != '']" 
                    group-by="cac:SellersItemIdentification/cbc:ID">
输出当前卖家将是使用分组键和其他字段的情况:

<xsl:value-of select="current-grouping-key()" />
<xsl:value-of select="cac:StandardItemIdentification/cbc:ID" />
由于我不太了解XSL-FO,作为示例提供的XSLT只会输出模糊的表和行元素,但它应该会告诉您一般的想法

尝试以下XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" 
                xmlns:cac="cac" xmlns:cbc="cbc" exclude-result-prefixes="cac cbc">
    <xsl:output indent="yes"/>
    <xsl:template match="Invoice">
        <xsl:for-each-group select="cac:InvoiceLine/cac:Item" group-by="cac:AdditionalItemIdentification/cbc:ID">
            <table>
                <row><xsl:value-of select="cbc:Name" /></row>
                <xsl:for-each-group select="current-group()" group-by="cbc:Description">
                    <row><xsl:value-of select="cbc:Description" /></row>

                    <xsl:for-each-group select="current-group()[cac:SellersItemIdentification/cbc:ID != '']" group-by="cac:SellersItemIdentification/cbc:ID">
                        <row>
                            <xsl:value-of select="current-grouping-key()" /> - <xsl:value-of select="cac:StandardItemIdentification/cbc:ID" />
                        </row>
                    </xsl:for-each-group>                    
                </xsl:for-each-group>
            </table>
        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>
这应该根据您提供的样本输出以下内容,其中仅包括Groucho,而不包括可怜的老Zeppo或Harpo

<table>
   <row>CONSULTANCY</row>
   <row>Snide Remarks</row>
   <row>Groucho - 2014-02-24</row>
</table>
<table>
   <row>EXPENSES INCURRED</row>
   <row>Cigars</row>
</table>

那么你面临的问题是什么?您的代码对每个组都执行select=../cbc:DescriptionTested,但在您发布的输入代码段中,我甚至找不到名为cbc:DescriptionTested的元素。您可能希望避免for循环。XSLT首先是一种模式匹配练习。我将把它分为两个步骤:第一步:将源XML转换成具有正确结构的XML格式,第二步:用FO布局装饰它。@stwissel:不幸的是,XML格式无法更改,因为它是政府标准。或者你的意思是将相关数据放入某种临时xml文件或数组中,然后从中提取数据?@MartinHonnen:你说得对-cbc:DescriptionEnded一定是某种复制/粘贴错误-应该是cvc:Description,我已经相应地更正了上面的帖子。嗨,Lars,第二个选择就是我的意思。将固定的政府格式转换为以正确的顺序包含所需内容的格式,并使用第二个样式表将其输入XSL:FO,该样式表进行FO装饰。在一切正常后,您不需要写出temp格式,在开发过程中,中间格式是一个很好的调试入口点