我只想知道是否可以在match
元素的xsl:template
属性中使用正则表达式。
例如,假设我有以下XML文档:
<greeting>
<aaa>Hello</aaa>
<bbb>Good</bbb>
<ccc>Excellent</ccc>
<dddline>Line</dddline>
</greeting>
现在XSLT转换上面的文档:
<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>
当我尝试在matches(node-name(*),'line$')
元素的match
属性中使用语法xsl:template
时,它会检索错误消息。我可以在match
属性中使用正则表达式吗?
非常感谢
答案 0 :(得分:15)
这是正确的XSLT 1.0匹配方式(在XSLT 2.0中使用matches()函数和真实的RegEx作为pattern
参数):
匹配名称中包含'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>
答案 1 :(得分:5)
在XSLT 1.0(以及2.0中)中,对于您的示例(但它不是正则表达式):
<xsl:template match="*[contains(name(), 'line')]">
<xsl:value-of select="."/>
</xsl:template>
并实现字符串结束匹配:
<xsl:template match="*[contains(concat(name(), '
'), 'line
')]">
<xsl:value-of select="."/>
</xsl:template>
在XSLT 2.0中,您当然可以使用matches()
函数代替contains()
。