XSLT:逐页遍历一系列元素

时间:2012-10-19 11:10:15

标签: xml xslt xpath

我想转换这个XML来创建标签页面作为我的XSLT输出,让我们说每页3个,所以我最终得到这样的东西:

我可以做我需要的一切,除了把它们分成几页。

INPUT XML:
<root>
   <element>a</element>
   <element>b</element>
   <element>c</element>
   <element>e</element>
   <element>f</element>
   <element>g</element>
   <element>h</element>
   <element>i</element>
</root>

XSLT RESULT XML:
<root>
   <page num="1">
      <element>a</element>
      <element>b</element>
      <element>c</element>
   </page>
   <page num="2">
      <element>d</element>
      <element>e</element>
      <element>f</element>
   </page>
   <page num="3">
      <element>g</element>
      <element>h</element>
   </page>
</root>

我尝试position() mod X,但顺序似乎很重要,因为我试图打破xml 10个单独的文件,并且使用exsl:document这种方式会导致它每次都覆盖文件,只保留最后一个要素:

<exsl:document href="chunk-{position() mod 10}.xml">

似乎我需要按顺序循环遍历它们(1-3,然后是4-6,然后是7-8)。

注意:我在linux上使用xsltproc,因此它支持EXSL但不支持XSLT2.0。

2 个答案:

答案 0 :(得分:2)

您可以将示例输入转换为所需的输出,如下所示:

<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:param name="block-size" select="3"/>

<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>


<xsl:template match="root">
  <xsl:copy>
    <xsl:apply-templates select="element[(position() - 1) mod $block-size = 0]" mode="page"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="element" mode="page">
  <page num="{position()}">
    <xsl:apply-templates select=". | following-sibling::element[position() &lt; $block-size]"/>
  </page>
</xsl:template>

</xsl:stylesheet>

因此样式表会获取一个输入文档并创建一个输出文档,如示例所示。

您还提到了exsl:document,但我不确定您想要做什么,因为您想要的结果似乎是单个文档。因此,如果这是要求的一部分,请显示您要创建的不同文档的样本。

答案 1 :(得分:1)

试试这个:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="root">
    <xsl:copy>
      <xsl:apply-templates select="element[position() mod 3 = 1]" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="element">
    <page num="{position()}">
      <xsl:copy-of select=". | following-sibling::element[position() &lt; 3]" />
    </page>
  </xsl:template>
</xsl:stylesheet>

这是一个简单的例子,但它应该足以证明原理。