使用 XSLT 对平面 XML 进行分层编号?
Hierarchical numbering of flat XML with XSLT?
我有一个平面 XML 文档,我想对其进行分层编号。这甚至可能 - <xsl:number ... count=''>
?
XML-来源(部分和简化)
<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 元素。此处是否可以进行分层编号?
我不认为你可以用 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" 解决了编号问题。
<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>
试试这个
我有一个平面 XML 文档,我想对其进行分层编号。这甚至可能 - <xsl:number ... count=''>
?
XML-来源(部分和简化)
<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 元素。此处是否可以进行分层编号?
我不认为你可以用 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" 解决了编号问题。
<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>
试试这个