2016-12-11 57 views
1

我試圖修改一些處理docbook文檔到LaTeX的dblatex XSLT代碼。我們爲當地的需求做了很多mod,但這個讓我難住。基於屬性打包

有一個「觀衆」屬性,幾乎可以出現在任何docbook XML元素上。在我們的文檔中,大多數元素都沒有標註這個屬性,但有些元素標記爲「技術」或「非技術」,例如

<chapter audience='tech'> 
    (lot of stuff) 
</chapter> 

而不是使用「分析」機制,我想換的是從處理具有這樣的屬性的元素產生的乳膠代碼,用膠乳標籤,即

\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

您可以使用mode屬性,自XSLT 1.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> 
+0

這是否需要我指定模式允許的所有元素的模式以擁有@audience attr?我當然不希望這樣做(docbook中有100多個元素,並且dblatex代碼已經足夠複雜了)。猜猜我必須嘗試一下,看看我是否可以省略上面的「secondRun」。 –

+0

您可以省略'secondRun'模式,我只是用它來說明機制。一般來說,如果'xsl:apply-templates'元素指定了一個模式,那麼它只會應用該模式的模板。否則,它應用不屬於任何模式的模板(即默認行爲)。相反,指定模式的模板只能通過相同模式的「xsl:apply-templates」進行匹配。 – Meyer

+0

@Mike Maxwell,這個答案是否足夠,還是需要進一步的幫助? – Meyer