Regular Expressions in xsl:template match attribute

后端 未结 2 2023
长发绾君心
长发绾君心 2020-12-10 06:53

I just want to know if it\'s possible to use regular expressions in the match attribute of the xsl:template element. For example, suppose I have th

相关标签:
2条回答
  • 2020-12-10 07:25

    Here is the correct XSLT 1.0 way of matching (in XSLT 2.0 use the matches() function with a real RegEx as the pattern argument):

    Matching an element whose name contains 'line':

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

    Matching an element whose name ends in 'line':

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

    @Tomalak provided another XSLT 1.0 way of finding names that end with a given string. His solution uses a special character that is guaranteed not to be ever present in any name. My solution can be applied to find if any string (not only a name of an element) ends with another given string.

    In XSLT 2.x :

    Use: matches(name(), '.*line$') to match names that end with the string "line"

    This transformation:

    <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>
    

    when applied on the XML document:

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

    Copies to the output only the element, whose name ends with the string "line":

    <ffffdline>Line</ffffdline>
    

    While this transformation (uses 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>
    

    copies to the output all elements, whose names contain the string "line":

    <bblineb>Good</bblineb>
    <ffffdline>Line</ffffdline>
    
    0 讨论(0)
  • 2020-12-10 07:26

    In XSLT 1.0 (and 2.0, too), for your example (it's not a regex, though):

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

    and to achieve an end-of-string match:

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

    In XSLT 2.0 you can of course use the matches() function in place of contains().

    0 讨论(0)
提交回复
热议问题