XSLT 1.0 - 使用子上下文重复 table 不起作用
XSLT 1.0 - repeating table using child context doesn't work
我正在使用下面的XML:
<root>
<Products name="product01">
<Instruments name="ins01"/>
<Instruments name="ins02"/>
<Instruments name="ins01"/>
</Products>
<Products name="product02">
<Instruments name="random text A">
<Bill name="A"/>
</Instruments>
<Instruments name="random text B and C">
<Bill name="B">
<Notes>some text</Notes>
</Bill>
<Bill name="C">
<Notes>some text</Notes>
</Bill>
</Instruments>
<Instruments name="random text A and B">
<Bill name="A">
<Notes>some text</Notes>
</Bill>
<Bill name="B">
<Notes>some text</Notes>
</Bill>
</Instruments>
<Instruments name="random text B">
<Bill name="B">
<Notes>some text</Notes>
</Bill>
</Instruments>
<Instruments name="random text C">
<Bill name="C">
<Notes>some text</Notes>
</Bill>
</Instruments>
<Instruments name="random text C and A">
<Bill name="C">
<Notes>some text</Notes>
</Bill>
<Bill name="A">
<Notes>some text</Notes>
</Bill>
</Instruments>
</Products>
</root>
首先,我在 Products 之后分组,然后在 Bills 之后分组,在左侧 table-column,而右侧 table-column 应该只显示 Instruments name,基于 Bill从第一列开始分组。作为上述 XML 的示例,我正在努力实现这一目标:
product02
Bill Type: A random text A
random text A and B
random text C and A
Bill Type: B random text B and C
random text A and B
random text B
Bill Type: C random text B and C
random text C
random text C and A
我的模板示例如下:
<xsl:key name="groupProducts" match="/root/Products/Instruments/Bill" use="../../@name" />
<xsl:key name="groupBilling" match="/root/Products/Instruments/Bill" use="concat(../../@name,@name)" />
<xsl:template name="myTemplate">
<fo:block>
<fo:table>
<fo:table-column column-width="proportional-column-width(1)" />
<fo:table-body>
<xsl:for-each select="/root/Products/Instruments/Bill[generate-id(.) = generate-id(key('groupProducts',../../@name)[1])]">
<fo:table-row>
<fo:table-cell>
<fo:block font-weight="bold" margin-top="4pt">
<xsl:value-of select="../../@name" />
</fo:block>
<fo:block>
<fo:table>
<fo:table-column column-width="50.000" column-number="1" />
<fo:table-column column-width="50.000" column-number="2" />
<fo:table-body>
<xsl:for-each select="/root/Products/Instruments/Bill[generate-id(.) = generate-id(key('groupBilling',concat(current()/../../@name,@name))[1])]">
<fo:table-row>
<fo:table-cell>
<fo:block color="blue">
Bill Type: <xsl:value-of select="@name" /></fo:block>
<fo:block />
</fo:table-cell>
<fo:table-cell>
<fo:block>
<fo:table>
<fo:table-column column-width="proportional-column-width(1)" />
<fo:table-body>
<xsl:for-each select="../.">
<fo:table-row>
<fo:table-cell>
<fo:block>
<xsl:value-of select="@name" />
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:block>
</xsl:template>
对于右侧 table 列的 for-each,我还尝试了以下操作:
<xsl:for-each select="../.">
../*[score/@naam = current()/score/@naam]
../node()[score/@naam = current()/score/@naam]
/root/Products/Instruments
,但 none 有效。
非常感谢任何帮助。
虽然我无法遵循您尝试使用 fo
命名空间的 XSLT,但请考虑这个缩短的 XSLT 运行 Muenchian 方法呈现所需输出的 HTML 版本:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="bill_key" match="Bill" use="@name"/>
<xsl:template match="/root">
<html>
<xsl:apply-templates select="Products[descendant::Bill]"/>
</html>
</xsl:template>
<xsl:template match="Products">
<table>
<tr>
<td><xsl:value-of select="@name"/></td>
<td></td>
</tr>
<xsl:apply-templates select="Instruments"/>
<tr></tr>
</table>
</xsl:template>
<xsl:template match="Instruments">
<xsl:apply-templates select="Bill[generate-id() =
generate-id(key('bill_key', @name))]"/>
</xsl:template>
<xsl:template match="Bill">
<xsl:for-each select="key('bill_key', @name)">
<tr>
<xsl:if test="position() = 1">
<td><xsl:value-of select="concat('Bill Type: ', @name)"/></td>
</xsl:if>
<xsl:if test="position() > 1">
<td></td>
</xsl:if>
<td><xsl:value-of select="../@name"/></td>
</tr>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
希望您可以根据自己的 fo
样式调整 <table>
、<tr>
、<td>
标签。
Online Demo (点击HTML查看输出)
HTML Table 输出
product02
Bill Type: A random text A
random text A and B
random text C and A
Bill Type: B random text B and C
random text A and B
random text B
Bill Type: C random text B and C
random text C
random text C and A
我正在使用下面的XML:
<root>
<Products name="product01">
<Instruments name="ins01"/>
<Instruments name="ins02"/>
<Instruments name="ins01"/>
</Products>
<Products name="product02">
<Instruments name="random text A">
<Bill name="A"/>
</Instruments>
<Instruments name="random text B and C">
<Bill name="B">
<Notes>some text</Notes>
</Bill>
<Bill name="C">
<Notes>some text</Notes>
</Bill>
</Instruments>
<Instruments name="random text A and B">
<Bill name="A">
<Notes>some text</Notes>
</Bill>
<Bill name="B">
<Notes>some text</Notes>
</Bill>
</Instruments>
<Instruments name="random text B">
<Bill name="B">
<Notes>some text</Notes>
</Bill>
</Instruments>
<Instruments name="random text C">
<Bill name="C">
<Notes>some text</Notes>
</Bill>
</Instruments>
<Instruments name="random text C and A">
<Bill name="C">
<Notes>some text</Notes>
</Bill>
<Bill name="A">
<Notes>some text</Notes>
</Bill>
</Instruments>
</Products>
</root>
首先,我在 Products 之后分组,然后在 Bills 之后分组,在左侧 table-column,而右侧 table-column 应该只显示 Instruments name,基于 Bill从第一列开始分组。作为上述 XML 的示例,我正在努力实现这一目标:
product02
Bill Type: A random text A
random text A and B
random text C and A
Bill Type: B random text B and C
random text A and B
random text B
Bill Type: C random text B and C
random text C
random text C and A
我的模板示例如下:
<xsl:key name="groupProducts" match="/root/Products/Instruments/Bill" use="../../@name" />
<xsl:key name="groupBilling" match="/root/Products/Instruments/Bill" use="concat(../../@name,@name)" />
<xsl:template name="myTemplate">
<fo:block>
<fo:table>
<fo:table-column column-width="proportional-column-width(1)" />
<fo:table-body>
<xsl:for-each select="/root/Products/Instruments/Bill[generate-id(.) = generate-id(key('groupProducts',../../@name)[1])]">
<fo:table-row>
<fo:table-cell>
<fo:block font-weight="bold" margin-top="4pt">
<xsl:value-of select="../../@name" />
</fo:block>
<fo:block>
<fo:table>
<fo:table-column column-width="50.000" column-number="1" />
<fo:table-column column-width="50.000" column-number="2" />
<fo:table-body>
<xsl:for-each select="/root/Products/Instruments/Bill[generate-id(.) = generate-id(key('groupBilling',concat(current()/../../@name,@name))[1])]">
<fo:table-row>
<fo:table-cell>
<fo:block color="blue">
Bill Type: <xsl:value-of select="@name" /></fo:block>
<fo:block />
</fo:table-cell>
<fo:table-cell>
<fo:block>
<fo:table>
<fo:table-column column-width="proportional-column-width(1)" />
<fo:table-body>
<xsl:for-each select="../.">
<fo:table-row>
<fo:table-cell>
<fo:block>
<xsl:value-of select="@name" />
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:block>
</xsl:template>
对于右侧 table 列的 for-each,我还尝试了以下操作:
<xsl:for-each select="../.">
../*[score/@naam = current()/score/@naam]
../node()[score/@naam = current()/score/@naam]
/root/Products/Instruments
,但 none 有效。
非常感谢任何帮助。
虽然我无法遵循您尝试使用 fo
命名空间的 XSLT,但请考虑这个缩短的 XSLT 运行 Muenchian 方法呈现所需输出的 HTML 版本:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="bill_key" match="Bill" use="@name"/>
<xsl:template match="/root">
<html>
<xsl:apply-templates select="Products[descendant::Bill]"/>
</html>
</xsl:template>
<xsl:template match="Products">
<table>
<tr>
<td><xsl:value-of select="@name"/></td>
<td></td>
</tr>
<xsl:apply-templates select="Instruments"/>
<tr></tr>
</table>
</xsl:template>
<xsl:template match="Instruments">
<xsl:apply-templates select="Bill[generate-id() =
generate-id(key('bill_key', @name))]"/>
</xsl:template>
<xsl:template match="Bill">
<xsl:for-each select="key('bill_key', @name)">
<tr>
<xsl:if test="position() = 1">
<td><xsl:value-of select="concat('Bill Type: ', @name)"/></td>
</xsl:if>
<xsl:if test="position() > 1">
<td></td>
</xsl:if>
<td><xsl:value-of select="../@name"/></td>
</tr>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
希望您可以根据自己的 fo
样式调整 <table>
、<tr>
、<td>
标签。
Online Demo (点击HTML查看输出)
HTML Table 输出
product02
Bill Type: A random text A
random text A and B
random text C and A
Bill Type: B random text B and C
random text A and B
random text B
Bill Type: C random text B and C
random text C
random text C and A