使用 XSLT 创建动态 XSL-FO 表

发布于 2024-12-05 22:34:49 字数 8410 浏览 0 评论 0原文

我正在 xsl-fo 中创建一个表,其中元素数量未定义(indtr)。

我想知道是否有一个聪明的方法来做到这一点?

这是我的输入 xml 文件

<pr-levels>
    <prs>
        <pr_nme><![CDATA[Level 1]]></pr_nme>
        <nt><![CDATA[standards:]]></nt>
        <b_is>
            <indtr id="5684"><![CDATA[cell_1]]></indtr>
            <indtr id="5684"><![CDATA[cell_2]]></indtr>
            <indtr id="5684"><![CDATA[cell_3]]></indtr>
            <indtr id="5684"><![CDATA[cell_4]]></indtr>
        </b_is>
    </prs>
    <prs>
        <pr_nme><![CDATA[Level 2]]></pr_nme>
        <nt><![CDATA[standards:]]></nt>
        <b_is>
            <indtr id="5684"><![CDATA[cell_1]]></indtr>
        </b_is>
    </prs>
    <prs>
        <pr_nme><![CDATA[Level 3]]></pr_nme>
        <nt><![CDATA[standards:]]></nt>
        <b_is>
            <indtr id="5684"><![CDATA[cell_1]]></indtr>
            <indtr id="5684"><![CDATA[cell_2]]></indtr>
        </b_is>
    </prs>
    <prs>
        <pr_nme><![CDATA[Level 4]]></pr_nme>
        <nt><![CDATA[standards:]]></nt>
        <b_is>
            <indtr id="5684"><![CDATA[cell_1]]></indtr>
            <indtr id="5684"><![CDATA[cell_2]></indtr>
            <indtr id="5684"><![CDATA[cell_3]]></indtr>
            <indtr id="5684"><![CDATA[cell_4]></indtr>
            <indtr id="5684"><![CDATA[cell_5]]></indtr>
            <indtr id="5684"><![CDATA[cell_6]]></indtr>
            <indtr id="5684"><![CDATA[cell_7]]></indtr>
        </b_is>
    </prs>
    <prs>
        <pr_nme><![CDATA[Level 5]]></pr_nme>
        <nt><![CDATA[standards:]]></nt>
        <b_is>
            <indtr id="5684"><![CDATA[cell_1]]></indtr>
            <indtr id="5684"><![CDATA[cell_2]]></indtr>
            <indtr id="5684"><![CDATA[cell_3]]></indtr>
            <indtr id="5684"><![CDATA[cell_4]]></indtr>
            <indtr id="5684"><![CDATA[cell_5]]></indtr>
            <indtr id="5684"><![CDATA[cell_6]]></indtr>
            <indtr id="5684"><![CDATA[cell_7]]></indtr>
            <indtr id="5684"><![CDATA[cell_8]]></indtr>
            <indtr id="5684"><![CDATA[cell_9]]></indtr>
            <indtr id="5684"><![CDATA[cell_10]]></indtr>
            <indtr id="5684"><![CDATA[cell_11]]></indtr>
            <indtr id="5684"><![CDATA[cell_12]]></indtr>
            <indtr id="5684"><![CDATA[cell_13]]></indtr>
            <indtr id="5684"><![CDATA[cell_14]]></indtr>
            <indtr id="5684"><![CDATA[cell_15]]></indtr>
            <indtr id="5684"><![CDATA[cell_16]]></indtr>
            <indtr id="5684"><![CDATA[cell_17]]></indtr>
            <indtr id="5684"><![CDATA[cell_18]]></indtr>
            <indtr id="5684"><![CDATA[cell_19]]></indtr>
        </b_is>
    </prs>
</pr-levels>

这是我的 XSLT 模板,它生成 XSL-FO 表:

   <xsl:template match="pr-levels">
    <fo:table xsl:use-attribute-sets="table_p" break-after="page" force-page-count="no-force">
        <fo:table-column column-number="1" xsl:use-attribute-sets="table_col_p"/>
        <fo:table-column column-number="2" xsl:use-attribute-sets="table_col_p"/>
        <fo:table-column column-number="3" xsl:use-attribute-sets="table_col_p"/>
        <fo:table-column column-number="4" xsl:use-attribute-sets="table_col_p"/>
        <fo:table-column column-number="5" xsl:use-attribute-sets="table_col_p"/>

        <fo:table-header xsl:use-attribute-sets="table_header">
                <xsl:for-each select="prs/pr_nme">
                    <fo:table-cell>
                        <fo:block>
                            <xsl:apply-templates/>
                        </fo:block>
                    </fo:table-cell>
                </xsl:for-each>
        </fo:table-header>

        <fo:table-body >
            <fo:table-row>
                <xsl:for-each select="prs/nt">
                    <fo:table-cell>
                        <fo:block xsl:use-attribute-sets="nt" >
                            <xsl:apply-templates/>  
                        </fo:block>
                    </fo:table-cell>
                </xsl:for-each>
            </fo:table-row>

            <fo:table-row>
                <xsl:for-each select="prs/b_is">
                    <fo:table-cell padding="1pt">
                        <fo:block>
                            <xsl:value-of select="indtr[1]"/>   
                        </fo:block>
                    </fo:table-cell>
                </xsl:for-each>
            </fo:table-row>
            <fo:table-row>
                <xsl:for-each select="prs/b_is">
                    <fo:table-cell padding="1pt">
                        <fo:block>
                            <xsl:value-of select="indtr[2]"/>   
                        </fo:block>
                    </fo:table-cell>
                </xsl:for-each>
            </fo:table-row>
            <fo:table-row>
                <xsl:for-each select="prs/b_is">
                    <fo:table-cell padding="1pt">
                        <fo:block>
                            <xsl:value-of select="indtr[3]"/>   
                        </fo:block>
                    </fo:table-cell>
                </xsl:for-each>
            </fo:table-row>
            <fo:table-row>
                <xsl:for-each select="prs/b_is">
                    <fo:table-cell padding="1pt">
                        <fo:block>
                            <xsl:value-of select="indtr[4]"/>   
                        </fo:block>
                    </fo:table-cell>
                </xsl:for-each>
            </fo:table-row>
            <fo:table-row>
                <xsl:for-each select="prs/b_is">
                    <fo:table-cell padding="1pt">
                        <fo:block>
                            <xsl:value-of select="indtr[5]"/>   
                        </fo:block>
                    </fo:table-cell>
                </xsl:for-each>
            </fo:table-row>
        </fo:table-body>
      </fo:table>
   </xsl:template>

可能有 NULL、1,69 或任何数量的 < /code> 位于 中,但现在我只是对数字进行硬编码。我的问题是如何动态计算 indtr 的数量并在表中添加行。也许是xsl中的for循环?

________________________________________________________
| level 1  | level 2  | level 3  | level 4  | level 5  |
--------------------------------------------------------
|standards:|standards:|standards:|standards:|standards:|
--------------------------------------------------------
| cell 1   | cell 1   | cell 1   | cell 1   | cell 1   |
--------------------------------------------------------
| cell 2   | cell 2   | cell 2   | cell 2   | cell 2   |
--------------------------------------------------------
|          | cell 3   | cell 3   | cell 3   | cell 3   |
--------------------------------------------------------
|          | cell 4   |          |          | cell 4   |
--------------------------------------------------------
|          |          |          |          | cell 5   |
--------------------------------------------------------
|          |          |          |          | cell 6   |
--------------------------------------------------------

I am creating a table in xsl-fo, with undefined number of elements (indtr).

I wonder if there a smart way to do this?

Here is my input xml file

<pr-levels>
    <prs>
        <pr_nme><![CDATA[Level 1]]></pr_nme>
        <nt><![CDATA[standards:]]></nt>
        <b_is>
            <indtr id="5684"><![CDATA[cell_1]]></indtr>
            <indtr id="5684"><![CDATA[cell_2]]></indtr>
            <indtr id="5684"><![CDATA[cell_3]]></indtr>
            <indtr id="5684"><![CDATA[cell_4]]></indtr>
        </b_is>
    </prs>
    <prs>
        <pr_nme><![CDATA[Level 2]]></pr_nme>
        <nt><![CDATA[standards:]]></nt>
        <b_is>
            <indtr id="5684"><![CDATA[cell_1]]></indtr>
        </b_is>
    </prs>
    <prs>
        <pr_nme><![CDATA[Level 3]]></pr_nme>
        <nt><![CDATA[standards:]]></nt>
        <b_is>
            <indtr id="5684"><![CDATA[cell_1]]></indtr>
            <indtr id="5684"><![CDATA[cell_2]]></indtr>
        </b_is>
    </prs>
    <prs>
        <pr_nme><![CDATA[Level 4]]></pr_nme>
        <nt><![CDATA[standards:]]></nt>
        <b_is>
            <indtr id="5684"><![CDATA[cell_1]]></indtr>
            <indtr id="5684"><![CDATA[cell_2]></indtr>
            <indtr id="5684"><![CDATA[cell_3]]></indtr>
            <indtr id="5684"><![CDATA[cell_4]></indtr>
            <indtr id="5684"><![CDATA[cell_5]]></indtr>
            <indtr id="5684"><![CDATA[cell_6]]></indtr>
            <indtr id="5684"><![CDATA[cell_7]]></indtr>
        </b_is>
    </prs>
    <prs>
        <pr_nme><![CDATA[Level 5]]></pr_nme>
        <nt><![CDATA[standards:]]></nt>
        <b_is>
            <indtr id="5684"><![CDATA[cell_1]]></indtr>
            <indtr id="5684"><![CDATA[cell_2]]></indtr>
            <indtr id="5684"><![CDATA[cell_3]]></indtr>
            <indtr id="5684"><![CDATA[cell_4]]></indtr>
            <indtr id="5684"><![CDATA[cell_5]]></indtr>
            <indtr id="5684"><![CDATA[cell_6]]></indtr>
            <indtr id="5684"><![CDATA[cell_7]]></indtr>
            <indtr id="5684"><![CDATA[cell_8]]></indtr>
            <indtr id="5684"><![CDATA[cell_9]]></indtr>
            <indtr id="5684"><![CDATA[cell_10]]></indtr>
            <indtr id="5684"><![CDATA[cell_11]]></indtr>
            <indtr id="5684"><![CDATA[cell_12]]></indtr>
            <indtr id="5684"><![CDATA[cell_13]]></indtr>
            <indtr id="5684"><![CDATA[cell_14]]></indtr>
            <indtr id="5684"><![CDATA[cell_15]]></indtr>
            <indtr id="5684"><![CDATA[cell_16]]></indtr>
            <indtr id="5684"><![CDATA[cell_17]]></indtr>
            <indtr id="5684"><![CDATA[cell_18]]></indtr>
            <indtr id="5684"><![CDATA[cell_19]]></indtr>
        </b_is>
    </prs>
</pr-levels>

Here is my XSLT template that produces the XSL-FO table:

   <xsl:template match="pr-levels">
    <fo:table xsl:use-attribute-sets="table_p" break-after="page" force-page-count="no-force">
        <fo:table-column column-number="1" xsl:use-attribute-sets="table_col_p"/>
        <fo:table-column column-number="2" xsl:use-attribute-sets="table_col_p"/>
        <fo:table-column column-number="3" xsl:use-attribute-sets="table_col_p"/>
        <fo:table-column column-number="4" xsl:use-attribute-sets="table_col_p"/>
        <fo:table-column column-number="5" xsl:use-attribute-sets="table_col_p"/>

        <fo:table-header xsl:use-attribute-sets="table_header">
                <xsl:for-each select="prs/pr_nme">
                    <fo:table-cell>
                        <fo:block>
                            <xsl:apply-templates/>
                        </fo:block>
                    </fo:table-cell>
                </xsl:for-each>
        </fo:table-header>

        <fo:table-body >
            <fo:table-row>
                <xsl:for-each select="prs/nt">
                    <fo:table-cell>
                        <fo:block xsl:use-attribute-sets="nt" >
                            <xsl:apply-templates/>  
                        </fo:block>
                    </fo:table-cell>
                </xsl:for-each>
            </fo:table-row>

            <fo:table-row>
                <xsl:for-each select="prs/b_is">
                    <fo:table-cell padding="1pt">
                        <fo:block>
                            <xsl:value-of select="indtr[1]"/>   
                        </fo:block>
                    </fo:table-cell>
                </xsl:for-each>
            </fo:table-row>
            <fo:table-row>
                <xsl:for-each select="prs/b_is">
                    <fo:table-cell padding="1pt">
                        <fo:block>
                            <xsl:value-of select="indtr[2]"/>   
                        </fo:block>
                    </fo:table-cell>
                </xsl:for-each>
            </fo:table-row>
            <fo:table-row>
                <xsl:for-each select="prs/b_is">
                    <fo:table-cell padding="1pt">
                        <fo:block>
                            <xsl:value-of select="indtr[3]"/>   
                        </fo:block>
                    </fo:table-cell>
                </xsl:for-each>
            </fo:table-row>
            <fo:table-row>
                <xsl:for-each select="prs/b_is">
                    <fo:table-cell padding="1pt">
                        <fo:block>
                            <xsl:value-of select="indtr[4]"/>   
                        </fo:block>
                    </fo:table-cell>
                </xsl:for-each>
            </fo:table-row>
            <fo:table-row>
                <xsl:for-each select="prs/b_is">
                    <fo:table-cell padding="1pt">
                        <fo:block>
                            <xsl:value-of select="indtr[5]"/>   
                        </fo:block>
                    </fo:table-cell>
                </xsl:for-each>
            </fo:table-row>
        </fo:table-body>
      </fo:table>
   </xsl:template>

There could be NULL,1,69 or whatever numbers of <indtr>s in a <b_is>,but right now I just hard code the numbers.My question is how I can dynamically count the number of indtrs and add rows in my table.maybe a for loop in xsl?

________________________________________________________
| level 1  | level 2  | level 3  | level 4  | level 5  |
--------------------------------------------------------
|standards:|standards:|standards:|standards:|standards:|
--------------------------------------------------------
| cell 1   | cell 1   | cell 1   | cell 1   | cell 1   |
--------------------------------------------------------
| cell 2   | cell 2   | cell 2   | cell 2   | cell 2   |
--------------------------------------------------------
|          | cell 3   | cell 3   | cell 3   | cell 3   |
--------------------------------------------------------
|          | cell 4   |          |          | cell 4   |
--------------------------------------------------------
|          |          |          |          | cell 5   |
--------------------------------------------------------
|          |          |          |          | cell 6   |
--------------------------------------------------------

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

青瓷清茶倾城歌 2024-12-12 22:34:49

只是因为这是一个有趣的问题...

将多个硬编码的 fo:table-row 替换为:

<xsl:variable name="pr-levels" select="." />
<xsl:for-each
    select="1 to max(for $prs in prs
                       return count($prs/b_is/indtr))">
  <xsl:variable name="row" select="." as="xs:integer" />
  <fo:table-row>
    <xsl:for-each select="$pr-levels/prs">
      <fo:table-cell padding="1pt">
        <fo:block>
          <xsl:value-of select="b_is/indtr[$row]"/>   
        </fo:block>
      </fo:table-cell>
    </xsl:for-each>
  </fo:table-row>
</xsl:for-each>

Just because it's an interesting problem...

Replace the multiple hard-coded fo:table-row with:

<xsl:variable name="pr-levels" select="." />
<xsl:for-each
    select="1 to max(for $prs in prs
                       return count($prs/b_is/indtr))">
  <xsl:variable name="row" select="." as="xs:integer" />
  <fo:table-row>
    <xsl:for-each select="$pr-levels/prs">
      <fo:table-cell padding="1pt">
        <fo:block>
          <xsl:value-of select="b_is/indtr[$row]"/>   
        </fo:block>
      </fo:table-cell>
    </xsl:for-each>
  </fo:table-row>
</xsl:for-each>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文