使用XSLT对XML进行分层编号?

时间:2018-05-12 20:43:21

标签: xml xslt numbers hierarchical flat

我有一个平面的XML文档,我想按层次编号。这是否可能 - 使用<xsl:number ... count=''>

XML-Source(部分内容和简化版)

<modul>
  <p>
  <h1>A Heading
  <p>
  <figure>
    <img>
  <h2>A Heading
  <p>
  <h1>A Heading
  <p>
  <h2>A Heading
  <p>
  <h3>A Heading
  <p>
<modul>

所需的输出(html)

<html>
      <p>
      <h1>1. A Heading
      <p>
      <figure>
        <img>
      <h2>1.2 A Heading
      <p>
      <h1>2. A Heading
      <p>
      <h2>2.1 A Heading
      <p>
      <h3>2.1.1 A Heading
      <p>
</html>

样式表(部分)

  <xsl:template match="h1">
            <h1>
            <xsl:number count="h1"/>
                <xsl:text>. </xsl:text>
                <xsl:apply-templates/>
            </h1>
     </xsl:template>

     <xsl:template match="h2">
            <h2>
                <xsl:number count="h1 | h2" level="multiple" format="1.1.1."/>  
                <xsl:apply-templates/>  
            </h2>
     </xsl:template> 

我能够对所有h1和h2元素进行编号,但我得到的只是连续编号(所有h元素都是连续编号)。我不知道如何在下一级获得h2 / h3元素。这里的分层编号是否可能?

2 个答案:

答案 0 :(得分:1)

我认为你不能用level =“multiple”实现这个目标。

我认为您可以使用

获取(比方说)h3元素所需的数字
<xsl:template match="h3" mode="number">
  <xsl:number level="any" count="h1"/>
  <xsl:text>.</xsl:text>
  <xsl:number level="any" count="h2" from="h1"/>
  <xsl:text>.</xsl:text>
  <xsl:number level="any" count="h3" from="h2"/>
</xsl:template>

然后您可以为其他级别定义类似的模板规则,并使用<xsl:apply-templates select="." mode="number"/>获取部分的级别编号。

有几点需要注意:(a)我没有对此进行过测试,并且(b)XSLT 1.0中xsl:number的规则会使某些情况下的指定不足,并且已知不同的XSLT 1.0实现已经解释规则以不同的方式。 XSLT 2.0中的规则更加精确,在某些边缘情况下,结果与1.0规范的(某些读数)不同。

依靠CSS进行编号可能会提供替代解决方案。

另一种方法是使用位置分组将平面结构转换为HTML5嵌套截面结构,在这种情况下,level =“multiple”解决了编号问题。

答案 1 :(得分:0)

<xsl:template match="@*|node()">
       <xsl:copy>
           <xsl:apply-templates select="@*"/>
       </xsl:copy>
   </xsl:template>
    <xsl:template match="modul">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="p">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="figure">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="img">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="h1">
        <xsl:copy>
            <xsl:number count="h1" level="any" format="1"/>
            <xsl:text>. </xsl:text>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="h2">
        <xsl:copy>
            <xsl:number count="h1" level="any" format="1"/>
            <xsl:text>.</xsl:text>
            <xsl:number from="h1" count="h2" level="any"/>
            <xsl:text> </xsl:text>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="h3">
        <xsl:copy>
            <xsl:number count="h1" level="any" format="1"/>
            <xsl:text>.</xsl:text>
            <xsl:number from="h1" count="h2" level="any"/>
            <xsl:text>.</xsl:text>
            <xsl:number from="h2" count="h3" level="any"/>
            <xsl:text> </xsl:text>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

试试这个