我正在尝试修改一些将docbook文档处理成LaTeX的dblatex XSLT代码。我们已经为我们当地的需求做了很多改造,但这个让我感到难过。
“观众”属性几乎可以出现在任何docbook XML元素上。在我们的文档中,大多数元素都没有标记为此attr,但有些标记为'tech'或'nontech',例如。
<chapter audience='tech'>
(lot of stuff)
</chapter>
我不想使用“profiling”机制,而是将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代码,但不包含章节。
相反,如果我更改上面的xslt代码,那么它有一个明确的
<xsl:apply-templates select="."/>
然后我得到一个无限的递归。
从概念上讲,我想要做的是告诉xslt通过输出LaTeX wrapper \ technical {...}来处理具有@audience attr的XML元素,然后处理相同的元素而忽略@ audience ='科技的属性。
有办法做到这一点吗?我在其他地方使用xslt v1,虽然我想如果有必要使用xslt v2,我可以进行更改(不确定如何完成,但必须有办法...)
答案 0 :(得分:0)
您可以使用自XSLT 1.0以来可用的mode
属性。
模式可以区分匹配相同节点的模板,但执行不同的操作。因此,可以多次处理相同的元素。可以找到更多信息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>