2012-10-30 35 views
1

我正在製作XSLT模板以便將XML轉換爲LaTeX(然後是HTML)。我認爲XSLT並不是爲此而生,但它很有用。我唯一的問題是文本格式:如果在某些文本行中,我希望使用加粗斜體單詞,例如在HTML中語法爲「< i> </i>」,但「\ textit {} 「在LaTeX中。XSLT和文本格式

一種解決方案是將「i」聲明爲模板,但我不知道是否可以對每個已封裝的文本塊「自動」應用它(我不想在所有模板中明確地調用它)

對不起,我是這個技術的新手,也許很簡單的解決方案存在,但谷歌這次沒有幫助我。

任何建議將不勝感激。

編輯:例如:

XSL:

<xsl:template match="one"> 
<xsl:apply-templates select="two"/> 
</xsl:template> 

XML:

<one> 
<two>Some text with <i>italic</i> words</two> 
</one> 

所需的輸出:

"Some text with \textit{italic} words" 

而且我也不想做的事:

<xsl:apply-templates select="i"/> 
在我的所有模板

所以我在尋找一種方式來申請「全球」「我」的模板。

+1

請編輯問題並提供:1.源XML文檔(不大); 2.轉換的確切期望輸出; 3.對轉換必須實現的任何規則的解釋(不要指望XSLT專家知道關於Tex的任何內容)。 –

+0

你是對的(編輯) – Neozaru

回答

3

由於因爲這簡單:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="i"> 
    <xsl:text>\textit{</xsl:text> 
    <xsl:apply-templates/> 
    <xsl:text>}</xsl:text> 
</xsl:template> 
</xsl:stylesheet> 

當該變換被應用上提供的XML文檔:

<one> 
    <two>Some text with <i>italic</i> words</two> 
</one> 

有用,正確的結果產生:

Some text with \textit{italic} words 

說明

XSLT處理模型採用了一些built-in templates,使用被提供的任何XML文檔的默認處理如果XSLT程序員不提供匹配特定節點的模板。

特別是,任何元素節點的內置模板只發出<xsl:apply-templates/>,以便模板應用於其所有子級。

任何文本節點的內置模板都是將此文本節點複製到輸出。

這意味着我們不需要爲節點提供任何模板,只要它必須完成相應的內置模板。

這讓我們只留下一個i元素 - 所以我們提供了一個匹配模板i - 它簡單地包圍了「\ textit {」和「}」處理子元素的結果。

請注意

這是完全可以表達複雜的轉換而沒有指定單個<xsl:apply-templates><xsl:call-template><xsl:for-each><xsl:choose><xsl:when><xsl:otherwise><xsl:if>

這稱爲"push-style""pull-style"其中一個或所有這些指令而被廣泛用作反對。

「推式」風格表達了一個問題的最具說明性的解決方案,而「拉式」轉換表達了更「必要」的解決方案。

這是在XSLT的精神,並建議總是儘量產生儘可能多的「推」代碼儘可能

+0

非常感謝!現在,這會更容易,因爲我知道它是如何工作的;) – Neozaru

+0

@Neozaru,不客氣。 –

0

編輯:我現在增加了一個完整的XSL末的基礎上,OP的XML和XSL

這只是一個假設,因爲---在評論中指出的Dimitre ---我們無法準確看到您的XSL,輸入或期望的輸出。但是,你可能想要這樣的東西。

<xsl:template match="//i"> 
    <xsl:text>\textit{</xsl:text> 
    <xsl:apply-templates select="@*|node()"/> 
    <xsl:text>}</xsl:text> 
</xsl:template> 


    <!-- or with namespace --> 

<xsl:template match="//*[namespace-uri()='http://www.w3.org/1999/xhtml' and local-name()='i']"> 
    <xsl:text>\textit{</xsl:text> 
    <xsl:apply-templates select="@*|node()"/> 
    <xsl:text>}</xsl:text> 
</xsl:template> 



<!-- assumes there is a copy happening like: --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

添加這樣的一個模板到XSL,應使其每個在輸入中被執行。

(放入XSL只是拷貝一個HTML文檔時)看起來像輸出:

<!-- before --> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
    <title>test</title> 
    </head> 
    <body> 
    <p> 
     <i>This is Only a Test</i> 
    </p> 
    </body> 
</html> 


<!-- after --> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
    <title>test</title> 
    </head> 
    <body> 
    <p> 
     \textit{This is Only a Test} 
    </p> 
    </body> 
</html> 

如果您給我們更多的,我會更新這個更具體。

編輯:基於所述OP代碼的完整示例(即最終提供)

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="one"/> 
    </xsl:template> 

    <xsl:template match="one"> 
    <xsl:apply-templates select="two"/> 
    </xsl:template> 

    <xsl:template match="//i"> 
    <xsl:text>\textit{</xsl:text> 
    <xsl:apply-templates select="@*|node()"/> 
    <xsl:text>}</xsl:text> 
    </xsl:template> 

    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet>