xsl中的正则表达式:模板匹配属性

tt0*_*686 7 regex xml xslt xpath

我只想知道是否可以matchxsl:template元素的属性中使用正则表达式.例如,假设我有以下XML文档:

<greeting>
    <aaa>Hello</aaa>
    <bbb>Good</bbb>
    <ccc>Excellent</ccc>
    <dddline>Line</dddline>
</greeting>
Run Code Online (Sandbox Code Playgroud)

现在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>
Run Code Online (Sandbox Code Playgroud)

当我尝试在元素matches(node-name(*),'line$')match属性中使用语法时xsl:template,它会检索错误消息.我可以在match属性中使用正则表达式吗?

非常感谢

Dim*_*hev 15

这是正确的XSLT 1.0匹配方式(在XSLT 2.0中使用matches()函数和真实的RegEx作为pattern参数):

匹配名称包含的元素'line':

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

匹配名称以下结尾的元素'line':

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

@Tomalak提供了另一种XSLT 1.0方法来查找以给定字符串结尾的名称.他的解决方案使用了一个特殊字符,保证不会以任何名称出现.我的解决方案可用于查找是否有任何字符串(不仅是元素的名称)以另一个给定字符串结尾.

在XSLT 2.x中:

使用:matches(name(), '.*line$')匹配以字符串结尾的名称"line"

这种转变:

当应用于theis XML文档时:

<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>
Run Code Online (Sandbox Code Playgroud)

仅将输出名称以字符串结尾的元素复制到输出"line":

<greeting>
    <aaa>Hello</aaa>
    <bblineb>Good</bblineb>
    <ccc>Excellent</ccc>
    <dddline>Line</dddline>
</greeting>
Run Code Online (Sandbox Code Playgroud)

虽然这种转变(使用matches(name(), '.*line')):

<dddline>Line</dddline>
Run Code Online (Sandbox Code Playgroud)

将所有元素复制到输出,其名称包含字符串"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>
Run Code Online (Sandbox Code Playgroud)


Tom*_*lak 5

在XSLT 1.0(以及2.0)中,对于您的示例(但它不是正则表达式):

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

并实现字符串结束匹配:

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

在XSLT 2.0中,您当然可以使用该matches()函数代替contains().