XSL-FO 和正确使用 xsl:template 和 xsl:for-each
XSL-FO and correct use of xsl:template and xsl:for-each
您可以在下面看到 XML 和我尝试格式化的 XSL。一切正常,直到我尝试插入模板。显然我做错了什么。我正在尝试使用 template 和 for-each 在 table 中为嵌套在下的每个 <order_line_item>
添加一行<order_line_items>
并且在四个单元格中的每个单元格中都应该有嵌套在 <order_line_item>
下的四个值 你能帮忙吗?谢谢!
<hash>
<order_line_items type="array">
<order_line_item>
<document_currency_unit_price_after_discount_value amount="300.0" code="GBP">£300.00</document_currency_unit_price_after_discount_value>
<document_currency_net_after_main_discount amount="300.0" code="GBP">£300.00</document_currency_net_after_main_discount>
<description>Subscription</description>
<unit_quantity type="decimal">1.0</unit_quantity>
</order_line_item>
<order_line_item>
<document_currency_unit_price_after_discount_value amount="300.0" code="GBP">£200.00</document_currency_unit_price_after_discount_value>
<document_currency_net_after_main_discount amount="300.0" code="GBP">£200.00</document_currency_net_after_main_discount>
<description>Additional Services</description>
<unit_quantity type="decimal">1.0</unit_quantity>
</order_line_item>
<order_line_item>
<document_currency_unit_price_after_discount_value amount="300.0" code="GBP">£-50.00</document_currency_unit_price_after_discount_value>
<document_currency_net_after_main_discount amount="300.0" code="GBP">£-50.00</document_currency_net_after_main_discount>
<description>Discount</description>
<unit_quantity type="decimal">1.0</unit_quantity>
</order_line_item>
</order_line_items>
</hash>
XSL
<?xml version="1.0" encoding="UTF-8"?>
<xslt:stylesheet xmlns:date="http://exslt.org/dates-and-times" xmlns:str="http://exslt.org/strings" xmlns:xslt="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xf="http://www.ecrion.com/xf/1.0" xmlns:xc="http://www.ecrion.com/2008/xc" xmlns:xfd="http://www.ecrion.com/xfd/1.0" xmlns:svg="http://www.w3.org/2000/svg" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" extension-element-prefixes="date str">
<xslt:output indent="yes" encoding="utf-8"/>
<xsl:template match="/">
<fo:root font-size="9pt">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4" page-width="210mm" page-height="297mm">
<fo:region-body region-name="xsl-region-body" padding-top="0px" padding-bottom="0px" padding-left="0px" padding-right="0px" margin-top="15mm" margin-bottom="15mm" margin-left="1.5cm" margin-right="1.5cm" border-style="none" border-width="0px" border-color="" background="" background-repeat="no-repeat" background-position-horizontal="0px" background-position-vertical="0px" extent="0px" column-gap="0px" column-count="1" reference-orientation="0"/>
<fo:region-before region-name="xsl-region-before" display-align="after" extent="15mm" padding-top="0px" padding-bottom="0px" padding-left="0px" padding-right="0px" border-style="none" border-width="0px" border-color="" background="" background-repeat="no-repeat" background-position-horizontal="0px" background-position-vertical="0px" reference-orientation="0"/>
<fo:region-after region-name="xsl-region-after" display-align="before" extent="15mm" padding-top="0px" padding-bottom="0px" padding-left="0px" padding-right="0px" border-style="none" border-width="0px" border-color="" background="" background-repeat="no-repeat" background-position-horizontal="0px" background-position-vertical="0px" reference-orientation="0"/>
<fo:region-start region-name="xsl-region-start" extent="1.5cm" padding-top="0px" padding-bottom="0px" padding-left="0px" padding-right="0px" border-style="none" border-width="0px" border-color="" background="" background-repeat="no-repeat" background-position-horizontal="0px" background-position-vertical="0px" reference-orientation="0"/>
<fo:region-end region-name="xsl-region-end" extent="1.5cm" padding-top="0px" padding-bottom="0px" padding-left="0px" padding-right="0px" border-style="none" border-width="0px" border-color="" background="" background-repeat="no-repeat" background-position-horizontal="0px" background-position-vertical="0px" reference-orientation="0"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4">
<fo:flow flow-name="xsl-region-body">
<fo:table margin-bottom="5mm">
<fo:table-column column-width="25%"/>
<fo:table-column column-width="25%"/>
<fo:table-column column-width="25%"/>
<fo:table-column column-width="25%"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block>
Product
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
Quantity
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
Unit Price
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
Net Amount
</fo:block>
</fo:table-cell>
</fo:table-row>
<xsl:template match="hash/order_line_items">
<fo:table-row>
<xsl:for-each select="order_line_item">
<fo:table-cell>
<fo:block>
<xsl:value-of select="description">
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
<xsl:value-of select="document_currency_unit_price_after_discount_value">
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
<xsl:value-of select="document_currency_unit_price_after_discount_value">
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
<xsl:value-of select="unit_quantity">
</fo:block>
</fo:table-cell>
</xsl:for-each>
</fo:table-row>
</xsl:template>
</fo:table-body>
</fo:table>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xslt:stylesheet>
正如我在评论中所说,模板不能嵌套。您需要使用带有嵌套 xsl:for-each
指令的单个模板,或带有 xsl:apply-templates
指令的多个模板,将下一级节点传递到下一个模板。
在给定的示例中,您只需要一个模板,使用一条 xsl:for-each
指令为每个 order_line_item
创建一个 table 行。由于您希望以不同于输入中使用的顺序填充行中的单元格,因此最好单独填充它们。
这是一个简化的示例(创建一个HTML table):
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/hash">
<table>
<!-- header row -->
<tr>
<th>Product</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Net Amount</th>
</tr>
<!-- data rows -->
<xsl:for-each select="order_line_items/order_line_item">
<tr>
<td>
<xsl:value-of select="description"/>
</td>
<td>
<xsl:value-of select="unit_quantity"/>
</td>
<td>
<xsl:value-of select="document_currency_unit_price_after_discount_value"/>
</td>
<td>
<xsl:value-of select="document_currency_net_after_main_discount"/>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
您可以在下面看到 XML 和我尝试格式化的 XSL。一切正常,直到我尝试插入模板。显然我做错了什么。我正在尝试使用 template 和 for-each 在 table 中为嵌套在下的每个 <order_line_item>
添加一行<order_line_items>
并且在四个单元格中的每个单元格中都应该有嵌套在 <order_line_item>
下的四个值 你能帮忙吗?谢谢!
<hash>
<order_line_items type="array">
<order_line_item>
<document_currency_unit_price_after_discount_value amount="300.0" code="GBP">£300.00</document_currency_unit_price_after_discount_value>
<document_currency_net_after_main_discount amount="300.0" code="GBP">£300.00</document_currency_net_after_main_discount>
<description>Subscription</description>
<unit_quantity type="decimal">1.0</unit_quantity>
</order_line_item>
<order_line_item>
<document_currency_unit_price_after_discount_value amount="300.0" code="GBP">£200.00</document_currency_unit_price_after_discount_value>
<document_currency_net_after_main_discount amount="300.0" code="GBP">£200.00</document_currency_net_after_main_discount>
<description>Additional Services</description>
<unit_quantity type="decimal">1.0</unit_quantity>
</order_line_item>
<order_line_item>
<document_currency_unit_price_after_discount_value amount="300.0" code="GBP">£-50.00</document_currency_unit_price_after_discount_value>
<document_currency_net_after_main_discount amount="300.0" code="GBP">£-50.00</document_currency_net_after_main_discount>
<description>Discount</description>
<unit_quantity type="decimal">1.0</unit_quantity>
</order_line_item>
</order_line_items>
</hash>
XSL
<?xml version="1.0" encoding="UTF-8"?>
<xslt:stylesheet xmlns:date="http://exslt.org/dates-and-times" xmlns:str="http://exslt.org/strings" xmlns:xslt="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xf="http://www.ecrion.com/xf/1.0" xmlns:xc="http://www.ecrion.com/2008/xc" xmlns:xfd="http://www.ecrion.com/xfd/1.0" xmlns:svg="http://www.w3.org/2000/svg" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" extension-element-prefixes="date str">
<xslt:output indent="yes" encoding="utf-8"/>
<xsl:template match="/">
<fo:root font-size="9pt">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4" page-width="210mm" page-height="297mm">
<fo:region-body region-name="xsl-region-body" padding-top="0px" padding-bottom="0px" padding-left="0px" padding-right="0px" margin-top="15mm" margin-bottom="15mm" margin-left="1.5cm" margin-right="1.5cm" border-style="none" border-width="0px" border-color="" background="" background-repeat="no-repeat" background-position-horizontal="0px" background-position-vertical="0px" extent="0px" column-gap="0px" column-count="1" reference-orientation="0"/>
<fo:region-before region-name="xsl-region-before" display-align="after" extent="15mm" padding-top="0px" padding-bottom="0px" padding-left="0px" padding-right="0px" border-style="none" border-width="0px" border-color="" background="" background-repeat="no-repeat" background-position-horizontal="0px" background-position-vertical="0px" reference-orientation="0"/>
<fo:region-after region-name="xsl-region-after" display-align="before" extent="15mm" padding-top="0px" padding-bottom="0px" padding-left="0px" padding-right="0px" border-style="none" border-width="0px" border-color="" background="" background-repeat="no-repeat" background-position-horizontal="0px" background-position-vertical="0px" reference-orientation="0"/>
<fo:region-start region-name="xsl-region-start" extent="1.5cm" padding-top="0px" padding-bottom="0px" padding-left="0px" padding-right="0px" border-style="none" border-width="0px" border-color="" background="" background-repeat="no-repeat" background-position-horizontal="0px" background-position-vertical="0px" reference-orientation="0"/>
<fo:region-end region-name="xsl-region-end" extent="1.5cm" padding-top="0px" padding-bottom="0px" padding-left="0px" padding-right="0px" border-style="none" border-width="0px" border-color="" background="" background-repeat="no-repeat" background-position-horizontal="0px" background-position-vertical="0px" reference-orientation="0"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4">
<fo:flow flow-name="xsl-region-body">
<fo:table margin-bottom="5mm">
<fo:table-column column-width="25%"/>
<fo:table-column column-width="25%"/>
<fo:table-column column-width="25%"/>
<fo:table-column column-width="25%"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block>
Product
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
Quantity
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
Unit Price
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
Net Amount
</fo:block>
</fo:table-cell>
</fo:table-row>
<xsl:template match="hash/order_line_items">
<fo:table-row>
<xsl:for-each select="order_line_item">
<fo:table-cell>
<fo:block>
<xsl:value-of select="description">
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
<xsl:value-of select="document_currency_unit_price_after_discount_value">
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
<xsl:value-of select="document_currency_unit_price_after_discount_value">
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
<xsl:value-of select="unit_quantity">
</fo:block>
</fo:table-cell>
</xsl:for-each>
</fo:table-row>
</xsl:template>
</fo:table-body>
</fo:table>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xslt:stylesheet>
正如我在评论中所说,模板不能嵌套。您需要使用带有嵌套 xsl:for-each
指令的单个模板,或带有 xsl:apply-templates
指令的多个模板,将下一级节点传递到下一个模板。
在给定的示例中,您只需要一个模板,使用一条 xsl:for-each
指令为每个 order_line_item
创建一个 table 行。由于您希望以不同于输入中使用的顺序填充行中的单元格,因此最好单独填充它们。
这是一个简化的示例(创建一个HTML table):
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/hash">
<table>
<!-- header row -->
<tr>
<th>Product</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Net Amount</th>
</tr>
<!-- data rows -->
<xsl:for-each select="order_line_items/order_line_item">
<tr>
<td>
<xsl:value-of select="description"/>
</td>
<td>
<xsl:value-of select="unit_quantity"/>
</td>
<td>
<xsl:value-of select="document_currency_unit_price_after_discount_value"/>
</td>
<td>
<xsl:value-of select="document_currency_net_after_main_discount"/>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>