如何分组编号页面?

时间:2014-05-15 11:02:10

标签: xml xslt

这是关于跨多个分组XML文件的页码编号,方法是使用索引文件来访问各个XML文件。必须为每个组重新开始编号,并跨越组中的所有文件。这是我的index.xml文件,它定义了组和单个文件:

<list>
  <numberGroup>
    <entry>
      <file>n1.xml</file>
    </entry>
    <entry>
      <file>n2.xml</file>
    </entry>
    <entry>
      <file>n3.xml</file>
    </entry>
  </numberGroup>
  <numberGroup>
    <entry>
      <file>p1.xml</file>
    </entry>
    <entry>
      <file>p2.xml</file>
    </entry>
    <entry>
      <file>p3.xml</file>
    </entry>
  </numberGroup>
  <numberGroup>
    <entry>
      <file>a1.xml</file>
    </entry>
    <entry>
      <file>a3.xml</file>
    </entry>
  </numberGroup>
</list>

所有<file> s n1.xmln2.xml等都有许多标记<page/>,这些标记在转换过程中会转换为页码。 (<span class="r" id="pg12">...</span>

这是我到目前为止的模板:

<xsl:template match="page">
<xsl:variable name="vRoot" select="generate-id(/)"/>
<xsl:variable name="vPage" select="$vFiles[$vRoot = generate-id(document(.))]"/>
<span class="r">
  <xsl:attribute name="id">pg<xsl:value-of select="count(document( (.|$vPage)/preceding::file)//page | (.|$vPage)/preceding::page) + 1">
  </xsl:value-of></xsl:attribute>
       ...
</span>
</xsl:template>

问题是,对于每个新numberGroup,编号不会重新开始。

有什么建议吗?。

1 个答案:

答案 0 :(得分:1)

考虑所有page元素的完整节点集,您正在计算元素。如果要重新启动每个numberGroup中的编号,则必须在此上下文中选择它们。

我假设您的n1.xmlp1.xml文件具有以下格式:

<pages>
    <page/>
    <page/>
    <page/>
</pages>

您可以通过为numberGroup创建模板并在该上下文中选择numberGroup元素,将所选内容限制为每个page中的文件:

<xsl:template match="numberGroup">
    <xsl:apply-templates select="document(entry/file)//page"/>
</xsl:template>

现在,对于每个页面,您只需获取其position()

<xsl:template match="page">
    <span class="r" id="pg{position()}"/>
</xsl:template>

这会产生这样的结果:

<div>
   <span class="r" id="pg1"/>
   <span class="r" id="pg2"/>
   ...
   <span class="r" id="pg99"/> <!-- total pages of all files in the first group -->
</div>
<div>
   <span class="r" id="pg1"/>
   <span class="r" id="pg2"/>
   ...
   <span class="r" id="pg19"/> <!-- total pages in second group -->
</div>
<div>...</div>

所以解决方案应该比你尝试的解决方案简单得多。您不需要任何变量或复杂的XPath表达式。这是一个完整的样式表,应该产生类似于你期望的结果:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="numberGroup">
        <div>
            <xsl:apply-templates select="document(entry/file)//page"/>
        </div>
    </xsl:template>

    <xsl:template match="page">
        <span class="r" id="pg{position()}"/>
    </xsl:template>
</xsl:stylesheet>