首页 > 解决方案 > 使用 XSL 合并 PDF 中的常用行

问题描述

我是 XSL 的新手。我有一个 XML 文件,我正在使用 XSL 从中生成 pdf。我可以使用 Fo、FO 块以 PDF 格式显示下表,

在此处输入图像描述

这会完美地生成包含不同行中所有数据的表。

但是,我需要通过合并显示以下格式

在此处输入图像描述

以下是我尝试过的 xml 和 XSL 代码:

XML

"<DocumentElement>
  <Student>
    <Roll>1</Roll>
    <NAME>Mark</NAME>
    <Subject>1000502</Subject>
    <DESCRIPTION>Test_2046_1</DESCRIPTION>
    <Total>20</Total>
  </Student>
  <Student>
    <Roll>1</Roll>
    <NAME>Mark</NAME>
    <Subject>1117697</Subject>
    <DESCRIPTION>Test_2046_2</DESCRIPTION>
    <Total>20</Total>
  </Student>
  <Student>
    <Roll>2</Roll>
    <NAME>Henry</NAME>
    <Subject>1271267</Subject>
    <DESCRIPTION>Test_2046_3</DESCRIPTION>
    <Total>20</Total>
  </Student>
  <Student>
    <Roll>2</Roll>
    <NAME>Henry</NAME>
    <Subject>5013025</Subject>
    <Total>20</Total>
  </Student>
</DocumentElement>"

XSL

"<xsl:template match="DocumentElement">
    <fo:block break-before="page">
      <fo:table xsl:use-attribute-sets="data_table">
        <xsl:call-template name="StudentItemsHeading"/>
        <fo:table-body>
          <xsl:apply-templates select="Student"/>
        </fo:table-body>
      </fo:table>
    </fo:block>
  </xsl:template>
  <xsl:template name="StudentItemsHeading">
    <fo:table-header>
      <fo:table-row xsl:use-attribute-sets="table_headers">
        <fo:table-cell xsl:use-attribute-sets="bordered">
          <fo:block>Student ID#</fo:block>
        </fo:table-cell>
        <fo:table-cell xsl:use-attribute-sets="bordered">
          <fo:block>Student Name</fo:block>
        </fo:table-cell>
        <fo:table-cell xsl:use-attribute-sets="bordered">
          <fo:block>Subjects</fo:block>
        </fo:table-cell>
        <fo:table-cell xsl:use-attribute-sets="bordered">
          <fo:block>Subject Description</fo:block>
        </fo:table-cell>
        <fo:table-cell xsl:use-attribute-sets="bordered">
          <fo:block>Total Marks</fo:block>
        </fo:table-cell>
        <fo:table-cell xsl:use-attribute-sets="bordered">
          <fo:block>Min.</fo:block>
        </fo:table-cell>
        <fo:table-cell xsl:use-attribute-sets="bordered">
          <fo:block>Max.</fo:block>
        </fo:table-cell>
      </fo:table-row>
    </fo:table-header>
  </xsl:template>
  <xsl:template match="Student">
    <fo:table-row>
      <fo:table-cell xsl:use-attribute-sets="bordered">
        <fo:block white-space-collapse="false" xsl:use-attribute-sets="bold">
          <xsl:value-of select="Roll"/>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell xsl:use-attribute-sets="bordered">
        <fo:block>
          <xsl:value-of select="NAME"/>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell xsl:use-attribute-sets="bordered">
        <fo:block white-space-collapse="false" xsl:use-attribute-sets="bold">
          <xsl:value-of select="Subject"/>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell xsl:use-attribute-sets="bordered">
        <fo:block white-space-collapse="false" xsl:use-attribute-sets="bold">
          <xsl:value-of select="DESCRIPTION"/>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell xsl:use-attribute-sets="number_format bordered">
        <fo:block>
          <xsl:value-of select="Total"/>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell xsl:use-attribute-sets="number_format bordered">
        <fo:block>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell xsl:use-attribute-sets="number_format bordered">
        <fo:block>
        </fo:block>
      </fo:table-cell>
    </fo:table-row>
  </xsl:template>

请帮助如何实现这一目标。

标签: xmlxsltxsl-fo

解决方案


代替

<xsl:apply-templates select="Student"/>

利用

<xsl:for-each-group select="Student" group-by="Roll">
  <xsl:apply-templates select="current-group()"/>
</xsl:for-each-group>

然后在模板中Student使用,例如

  <xsl:template match="Student">
    <fo:table-row>
      <xsl:if test="position() = 1">
       <fo:table-cell xsl:use-attribute-sets="bordered" number-rows-spanned="{count(current-group())}">
        <fo:block white-space-collapse="false" xsl:use-attribute-sets="bold">
          <xsl:value-of select="Roll"/>
        </fo:block>
       </fo:table-cell>
       <fo:table-cell xsl:use-attribute-sets="bordered" number-rows-spanned="{count(current-group())}">
        <fo:block>
          <xsl:value-of select="NAME"/>
        </fo:block>
       </fo:table-cell>
      </xsl:if>
      <fo:table-cell xsl:use-attribute-sets="bordered">
        <fo:block white-space-collapse="false" xsl:use-attribute-sets="bold">
          <xsl:value-of select="Subject"/>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell xsl:use-attribute-sets="bordered">
        <fo:block white-space-collapse="false" xsl:use-attribute-sets="bold">
          <xsl:value-of select="DESCRIPTION"/>
        </fo:block>
      </fo:table-cell>
      <xsl:if test="position() = 1">
       <fo:table-cell xsl:use-attribute-sets="number_format bordered" number-rows-spanned="{count(current-group())}">
        <fo:block>
          <xsl:value-of select="Total"/>
        </fo:block>
       </fo:table-cell>
      </xsl:if>
      <fo:table-cell xsl:use-attribute-sets="number_format bordered">
        <fo:block>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell xsl:use-attribute-sets="number_format bordered">
        <fo:block>
        </fo:block>
      </fo:table-cell>
    </fo:table-row>
  </xsl:template>

假设将 XSLT 2 或 3 与 Saxon 9 或 10 一起使用。


推荐阅读