我正在尝试学习 XSLT(为了一些假期编码的乐趣)。我想我现在对基础知识(抓取子树、过滤掉元素和重命名元素)有了很好的理解。我遇到麻烦的地方是彻底重组 XML 结构。如果您有一个深层嵌套的结构并想将其展平,您会怎么做?
例如,假设我正在尝试将 docbook 片段转换为 html...
输入(文档):
<section>
<title>Title A</title>
<para>foo</para>
<para>bar</para>
<section>
<title>Title B</title>
<para>baz</para>
<para>biz</para>
<section>
<title>Title C</title>
<para>bing</para>
</section>
</section>
<section>
<title>Title D</title>
<para>fizzle</para>
</section>
</section>
输出(html):
<h1>Title A</h1>
<p>foo</p>
<p>bar</p>
<h2>Title B</h2>
<p>baz</p>
<p>biz</p>
<h3>Title C</h3>
<p>bing</p>
<h2>Title D</h2>
<p>fizzle</p>
这是 xsl:param
和 xsl:call-template
发挥作用的地方吗?
谢谢!
最佳答案
Carsten 的测试用例有效(稍作调整,您需要用/终止 xsl:value-of
),但始终使用 <h2>
作为标题。如果你想根据标题的嵌套层次使用不同的标题元素,那么你还需要一些额外的东西:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates />
</body>
</html>
</xsl:template>
<xsl:template match="title">
<xsl:choose>
<xsl:when test="count(ancestor::section) = 1">
<h1><xsl:value-of select="." /></h1>
</xsl:when>
<xsl:when test="count(ancestor::section) = 2">
<h2><xsl:value-of select="." /></h2>
</xsl:when>
<xsl:otherwise>
<h3><xsl:value-of select="." /></h3>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="para">
<p><xsl:value-of select="." /></p>
</xsl:template>
</xsl:stylesheet>
XPath 函数 count(ancestor::section)
将返回所有 <section>
的计数当前元素的父元素。在示例中,我使用了 <h1>
和 <h2>
对于两个最外层和<h3>
对于嵌套更深的任何东西,当然你可以在离题时使用其他差异。
甚至可以使用以下表达式动态生成航向后的数字:
<xsl:template match="title">
<xsl:variable name="heading">h<xsl:value-of select="count(ancestor::section)" /></xsl:variable>
<xsl:element name="{$heading}">
<xsl:value-of select="." />
</xsl:element>
</xsl:template>
xsl:variable
那里的部分创建了一个值为 h
的变量+ 嵌套级别。然后该变量可以用作 xsl:element
的参数允许您动态定义要创建的元素名称的元素。
跟进:如果您只想按照建议使用 h1-h6,您可以这样做:
<xsl:template match="title">
<xsl:variable name="hierarchy" select="count(ancestor::section)"/>
<xsl:variable name="heading">h<xsl:value-of select="$hierarchy" /></xsl:variable>
<xsl:choose>
<xsl:when test="$hierarchy > 6">
<h6 class="{$heading}"><xsl:value-of select="." /></h6>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{$heading}">
<xsl:value-of select="." />
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
此表达式使用 <h6 class="h...">
对于任何嵌套深度超过 6 的东西。它使用 <h1>
通过<h6>
对于所有其他层次结构级别。
关于xml - 展平 XSLT 中的深层嵌套结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1912802/