我正在尝试修改一些将docbook文档处理为LaTeX的dblatex XSLT代码。我们已经为我们的本地需求做了相当多的mod,但这一次我被难住了。
实际上,任何docbook XML元素上都有一个“audience”属性。在我们的文档中,大多数元素都没有标记为这个属性,但也有一些标记为“tech”或“for tech”,例如
<chapter audience='tech'>
(lot of stuff)
</chapter>我不想使用“分析”机制,而是想用一个LaTeX标记包装处理具有这样一个属性的元素所产生的LaTeX代码。
\technical{ \chapter (lots of stuff) }我尝试使用xslt代码来实现这种包装,如下所示:
<xsl:template match=".[@audience='tech']">
<xsl:text>\technical{</xsl:text>
<xsl:apply-templates/>
<xsl:text>}</xsl:text>
</xsl:template>不幸的是,这样做的结果是匹配该模板的XML元素不会得到处理,只有它的子元素才会得到处理(当xslt代码中没有@select属性时,这是预期的)。所以如果原件是
<chapter role='tech'>
<section>blah blah</section>
</chapter>然后,LaTeX输出将包含该部分的LaTeX代码,但不包含该章节的the代码。
相反,如果我更改上面的xslt代码,使其具有显式的
<xsl:apply-templates select="."/>然后我得到一个无限递归。
从概念上讲,我想要做的是告诉xslt通过输出LaTeX包装器\technical{...}来处理具有@audience属性的XML元素,然后在忽略@audience='tech‘属性的情况下处理相同的元素。
有没有办法做到这一点?我正在其他地方使用xslt v1,尽管我猜如果有必要使用xslt v2,我可以进行更改(不确定是如何实现的,但一定有办法……)
发布于 2016-12-12 04:03:08
您可以使用mode属性,该属性从XSLT1.0开始就可用。使用模式可以区分匹配相同节点但执行不同操作的模板。因此,可以多次处理相同的元素。更多信息可以在in the standard上找到。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates select="*" mode="firstRun"/>
</xsl:template>
<xsl:template match="chapter[@audience='tech']" mode="firstRun">
<xsl:text>\technical{</xsl:text>
<xsl:apply-templates select="." mode="secondRun"/>
<xsl:text>}</xsl:text>
</xsl:template>
<xsl:template match="chapter" mode="secondRun">
<xsl:text>\chapter{</xsl:text>
<xsl:value-of select="."/>
<xsl:text>}</xsl:text>
</xsl:template>
</xsl:stylesheet>https://stackoverflow.com/questions/41090337
复制相似问题