2010-06-20 116 views
6

我只想知道是否可以在xsl:template元素的match屬性中使用正則表達式。 例如,假設我有如下的XML文檔:當我嘗試使用語法matches(node-name(*),'line$')xsl:templatematch屬性xsl:template match屬性中的正則表達式

<xsl:stylesheet> 

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

    <xsl:template match="matches(node-name(*),'line')"> 
     <xsl:value-of select="."/> 
    </xsl:template> 

</xsl:stylesheet> 

<greeting> 
    <aaa>Hello</aaa> 
    <bbb>Good</bbb> 
    <ccc>Excellent</ccc> 
    <dddline>Line</dddline> 
</greeting> 

現在XSLT把上述文件元素,它將檢索錯誤消息。我可以在match屬性中使用正則表達式嗎?

非常感謝

+2

下一次,請你只閱讀文本框,在那裏說旁邊的複選框*」如何格式化:由4個空格縮進代碼「*。那麼你不必使用'<'等...... – 2010-06-20 22:34:42

+0

好問題(+1)。看到我的答案,這個答案在這個時候包含你的兩個相關問題的唯一完全正確的解決方案。 :) – 2010-06-21 02:50:53

回答

14

這裏是匹配(在XSLT 2.0使用匹配()函數與真正的正則表達式作爲pattern參數)的正確XSLT 1.0方式:

匹配的元件的名稱包含'line'

<xsl:template match="*[contains(name(), 'line')]"> 
    <!-- Whatever processing is necessary --> 
</xsl:template> 

匹配的元件,其名稱結束在'line'

<xsl:template match="*[substring(name(), string-length() -3) = 'line']"> 
    <!-- Whatever processing is necessary --> 
</xsl:template> 

@Tomalak提供了另一種查找以給定字符串結尾的名稱的XSLT 1.0方式。他的解決方案使用了一個特殊的角色,保證不會以任何名義出現。我的解決方案可以應用於查找是否有任何字符串(不僅是一個元素的名稱)以另一個給定的字符串結尾。

在XSLT 2中。X

使用matches(name(), '.*line$'),匹配以字符串"line"

這種轉變結尾的名稱:

當泰斯XML文檔施加:

<greeting> 
    <aaa>Hello</aaa> 
    <bblineb>Good</bblineb> 
    <ccc>Excellent</ccc> 
    <dddline>Line</dddline> 
</greeting> 

複製到輸出只元件,其名稱與字符串"line"結束:

<dddline>Line</dddline> 

雖然此轉換(使用matches(name(), '.*line')):

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="*[matches(name(), '.*line')]"> 
    <xsl:copy-of select="."/> 
</xsl:template> 

<xsl:template match="*[not(matches(name(), '.*line'))]"> 
    <xsl:apply-templates select="node()[not(self::text())]"/> 
</xsl:template> 
</xsl:stylesheet> 

副本輸出的所有元素,名稱中包含字符串"line"

<bblineb>Good</bblineb> 
<dddline>Line</dddline> 
+0

首先,非常感謝您的努力,這是我第一次在這個論壇上發表疑問,我真的很驚訝你的反應快。我錯過了我假裝使用的xslt版本,它會是2.0,是的,我想在字符串中找到字符串'line'。 再次感謝您的支持 – tt0686 2010-06-21 08:11:17

+0

@pedromarquescosta:不客氣。我已經用使用RegEx的請求的XSLT 2.0解決方案更新了我的答案。 – 2010-06-21 13:24:30

5

在XSLT 1.0(和2.0,太),爲你的榜樣(這不是一個正則表達式,雖然):

<xsl:template match="*[contains(name(), 'line')]"> 
    <xsl:value-of select="."/> 
</xsl:template> 

,並實現結束串的匹配:

<xsl:template match="*[contains(concat(name(), '&#xA;'), 'line&#xA;')]"> 
    <xsl:value-of select="."/> 
</xsl:template> 

在XSLT 2.0當然你也可以使用matches()功能到位的。

+0

@Dimitre:正如你所說的,LF不能是'name()'的一部分。所以,如果你不能使用XPath 2.0(和正則表達式),這將是一種匹配名稱的方式,該名稱在其末尾包含字符串「line」,而不是在任何地方。 OP似乎想要這樣做,因爲他提到了正則表達式''$'',並且他沒有指出他使用的XSLT版本。我本可以使用空間,或任何其他字符是非法的名稱。所以這完全沒有意義或不正確。 ;-) – Tomalak 2010-06-21 07:50:59

+0

好吧,我明白了。對於這個名字的作品。 – 2010-06-21 12:59:23