我正在尝试转换CHM(Microsoft HTML帮助)文件索引的内容,该索引使用XSL在非常任意的HTML列表中保存结构信息(请参阅第一个代码片段 - 实际索引文件的结构有点不同,但是那里的重要部分)。我查看了几个CHM文件的索引,但 ul , li 标签结构从不相同。只有一件事是静态的:有 param 标签,它们保存有关章节,部分,标题和HTML链接的信息
因此,我试图仅依靠某些 param 标签的深度信息将列表转换为XML结构(主要是转换为DocBook结构 - 请参阅第二个代码片段)
<ul>
<li>
<param attr="value"/>
<ul>
<li>
<param attr="value"/>
<ul>
<li>
<param attr="value"/>
</li>
</ul>
</li>
<li>
<param attr="value"/>
<ul>
<li>
<param attr="value"/>
</li>
<li>
<param attr="value"/>
</li>
</ul>
</li>
<li>
<param attr="value"/>
<ul>
<li>
<param attr="value"/>
</li>
</ul>
</li>
</ul>
</li>
</ul>
我已经设法将一些索引(类似于前面的代码片段)转换为DocBook结构,但问题是我的XSL样式表不够通用。如果有人有想法将类似的HTML列表转换为DocBook结构,只使用 param标签的深度信息,请给我一些指示。
例如,深度为 X 的param标签将转换为 book 元素,深度为 X + 1 将转换为章,等等 - 当然总是正确嵌套。
<book>
<title>value1</title>
<chapter>
<title>value2</title>
<section>
<title>value3</title>
</section>
</chapter>
<chapter>
<title>value4</title>
<section>
<title>value5</title>
</section>
<section>
<title>value6</title>
</section>
</chapter>
<chapter>
<title>value7</title>
<section>
<title>value8</title>
</section>
</chapter>
</book>
答案 0 :(得分:2)
如果你的主要问题是如何根据输入树中的深度生成不同的元素,那么下面的样式表演示了一种方法:首先,通过count()
元素来计算嵌套级别ancestor-or-self
axis,然后使用xsl:element
创建一个动态确定名称的元素。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="li">
<xsl:variable name="depth" select="count(ancestor-or-self::li)"/>
<xsl:variable name="tag">
<xsl:choose>
<xsl:when test="$depth = 1">book</xsl:when>
<xsl:when test="$depth = 2">chapter</xsl:when>
<xsl:otherwise>section</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="{$tag}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="param">
<title>
<xsl:value-of select="@attr"/>
</title>
</xsl:template>
</xsl:stylesheet>
编辑。这是另一种做同样的方式。这使用不同的模板来匹配不同深度的源元素。这可能更容易阅读,因为它消除了创建动态命名元素的需要。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="li[count(ancestor-or-self::li) = 1]">
<book>
<xsl:apply-templates/>
</book>
</xsl:template>
<xsl:template match="li[count(ancestor-or-self::li) = 2]">
<chapter>
<xsl:apply-templates/>
</chapter>
</xsl:template>
<xsl:template match="li[count(ancestor-or-self::li) > 2]">
<section>
<xsl:apply-templates/>
</section>
</xsl:template>
<xsl:template match="param">
<title>
<xsl:value-of select="@attr"/>
</title>
</xsl:template>
</xsl:stylesheet>