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() &gt; 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