2013-11-20 128 views
4

我有由出口XML與HTML標籤轉義例如,作爲XSL轉換爲嵌套的HTML標籤

<b>some text</b> 

的Java應用程序的一系列文件輸出的(我不能改變這種行爲)。

認爲然後使用該輸出必須有所有的HTML標籤逃到

&lt;b&gt;some text &lt;/b&gt; 

我用下面的XSLT逃脫標籤,但並不奇怪它並不適用於嵌套 html標籤的工作,例如應用程序那裏的

<u><b>A string of html</b></u> 

在XSLT轉換,我得到

&lt;u&gt;a string of html&lt;/u&gt; 

where nested <b> and </b> tags get removed altogether. 

我期待實現

&lt;u&gt;&lt;b&gt;A string of html&lt;/b&gt;&lt;/u&gt; 

我肯定有調整值的選擇或模板的一個簡單的答案,但我曾嘗試和慘淡經營

沒任何幫助,將不勝感激!

與嵌入式的HTML標籤

<?xml version="1.0" encoding="UTF-8"?> 
<Main> 
<Text><u><b>A string of html</b></u></Text> 
</Main> 

這樣的文檔是XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" encoding="UTF-8"/> 
<xsl:strip-space elements="*" /> 

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

<xsl:template match="Text/*"> 
    <xsl:value-of select="concat('&lt;',name(),'&gt;',.,'&lt;/',name(),'&gt;')" /> 
</xsl:template> 

</xsl:stylesheet> 

將會產生

<?xml version="1.0" encoding="UTF-8"?> 
<Main> 
    <Text>&lt;u&gt;A string of html&lt;/u&gt;</Text> 
</Main> 

內大膽的標籤已被丟棄,你可以看到。

任何人都可以幫助調整xslt嗎?

謝謝:-)

+1

+1表示清晰且合理的結構化問題。 –

+1

您想要「逃離」的任何標籤都有屬性(例如'link')? –

+0

是的,他們可以這樣做,但這是Tim C的解決方案所涵蓋的。無論如何謝謝您的回答! – user3012857

回答

4

試着改變你的當前Text/*模板,這個

<xsl:template match="Text//*"> 
    <xsl:value-of select="concat('&lt;',name(),'&gt;')" /> 
    <xsl:apply-templates /> 
    <xsl:value-of select="concat('&lt;/',name(),'&gt;')" /> 
</xsl:template> 

所以,Text//*將匹配文本元素的任何後代元素,而不僅僅是眼前的孩子。然後,您分別輸出打開和關閉模板,並在這些模板之間遞歸調用模板以處理「嵌套」元素。

當適用於您的示例XML,下面應該是輸出

<Main> 
    <Text>&lt;u&gt;&lt;b&gt;A string of html&lt;/b&gt;&lt;/u&gt;</Text> 
</Main> 
+0

謝謝蒂姆,你是明星。當你知道時,這非常簡單明瞭!我忘了所有關於XPath語法的知識。快樂編碼:-) – user3012857

1

因爲你的評價是你試圖「逃離」的標籤可能有帶屬性狀態,Tim C's solution是不夠的。你真正需要的是更多的東西像這樣(因爲你說有問題的標記是HTML我會假設你不需要關心的命名空間):

<xsl:template match="Text//*"> 
    <xsl:value-of select="concat('&lt;',name())" /> 
    <xsl:apply-templates select="@*" mode="escape" /> 
    <xsl:text>&gt;</xsl:text> 
    <xsl:apply-templates /> 
    <xsl:value-of select="concat('&lt;/',name(),'&gt;')" /> 
</xsl:template> 

<xsl:template match="@*" mode="escape"> 
    <xsl:value-of select="concat(' ', name(), '=&quot;')" /> 
    <xsl:call-template name="doubleEscapeQuotes" /> 
    <xsl:text>"</xsl:text> 
</xsl:template> 

<xsl:template name="doubleEscapeQuotes"> 
    <xsl:param name="value" select="string(.)" /> 
    <xsl:choose> 
    <xsl:when test="contains($value, '&quot;')"> 
     <xsl:value-of select="substring-before($value, '&quot;')" /> 
     <xsl:text>&amp;quot;</xsl:text> 
     <xsl:call-template name="doubleEscapeQuotes"> 
     <xsl:with-param name="value" select="substring-after($value, '&quot;')" /> 
     </xsl:call-template> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:value-of select="$value" /> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

這將轉化

<a title="An &quot;example&quot; website" href="http://example.com">link</a> 

&lt;a title="An &amp;quot;example&amp;quot; website" href="http://example.com"&gt;link&lt;/a&gt; 

但它仍然缺少一些必要的邏輯 - 你需要仔細逃生至少符號(&amp;amp;)和小於(&amp;lt;)跡象WEL l在屬性值之間的HTML元素的文本內容中,爲了使得到的標記在非轉義後保持良好格式(您可能還想逃避大於符號的可讀性,但這並不重要如&<)。

這是一個比剛開始時難得多的問題。 this question的各種答案可能會有所幫助。

+0

伊恩,你當然是絕對正確的,並且感謝你的更新,幸運的是我發現,沒有一個html標籤畢竟具有屬性,而且你是對的,它比第一個更復雜視線。希望我能接受這兩個答案! – user3012857