我们的目标是打印发票行,这些发票行首先按照被调用的服务类型分组,然后按作业描述和成员名称打印:
做实际工作
Gummo - 2014-03-03
Zeppo - 2014-02-24
Harpo - 2014-03-07
Snide备注
格劳乔 - 2014-02-24
竖琴演奏
Harpo - 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>
我们通过执行简单的for-each循环来启动我们的XSL样式表,该循环按cac对发票行进行分组:InvoiceLine / cac:Item / cac:AdditionalItemIdentification(顾问行标记为10000,费用行标记为20000);然后,我们需要确保每个咨询行首先按职务描述分组(cac:InvoiceLine / cac:Item / cbc:Description)。我们已经尝试了几次迭代,每个循环,每个组和使用密钥的解决方案。但是,它们似乎都依赖于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 -->
答案 0 :(得分:0)
最好尽可能避免重复代码。目前尚不清楚你是否只会有“咨询”和“费用发生”,但可以安全地假设没有。我还假设每个 InvoiceLine 可以有多个 Item 元素(尽管如果不是这样,解决方案仍然有用)。
无论如何,您可以从 AdditionalItemIdentification 对 Item 元素进行分组开始。这将为“咨询”和“费用发生”
创建您的组<xsl:for-each-group select="cac:InvoiceLine/cac:Item"
group-by="cac:AdditionalItemIdentification/cbc:ID">
然后,只需输出名称
即可完成每组的标题<xsl:value-of select="cbc:Name" />
现在,在当前组( Item )元素中,您需要按说明
进行分组<xsl:for-each-group select="current-group()"
group-by="cbc:Description">
最后,在此群组中(仍然是项目),您希望按 SellersItemIdentification 分组,但您可能需要额外检查,因为并非所有项目元素具有它们(在“Expenses Incurred”的情况下
<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>