开发者

Dynamic 'matches' statement in XSLT

开发者 https://www.devze.com 2023-03-06 23:12 出处:网络
I\'m trying to create an xslt function that dynamically \'matches\' for an element.In the function, I will pass two parameters - item()* and a comma delimited string.I tokenize the comma d开发者_开发技

I'm trying to create an xslt function that dynamically 'matches' for an element. In the function, I will pass two parameters - item()* and a comma delimited string. I tokenize the comma d开发者_开发技巧elimited string in a <xsl:for-each> select statement and then do the following:

select="concat('$di:meta[matches(@domain,''', current(), ''')][1]')"

Instead of the select statement 'executing' the xquery, it is just returning the string.

How can I get it to execute the xquery?

Thanks in advance!


The problem is that you are wrapping too much of the expression in the concat() function. When that evaluates, it returns a string that would be the XPath expression, rather than evaluating the XPath expression that uses the dynamic string for the REGEX match expression.

You want to use:

 <xsl:value-of select="$di:meta[matches(@domain
                                        ,concat('.*('
                                                ,current()
                                                ,').*')
                                        ,'i')][1]" />

Although, since you are now evaluating each term separately,rather than having each of those terms in a single regex pattern and selecting the first one, it will now return the first result from each match, rather than the first one from the sequence of matched items. That may or may not be what you want.

If you want the first item from the sequence of matched items, you could do something like this:

<!--Create a variable and assign a sequence of matched items -->
<xsl:variable name="matchedMetaSequence" as="node()*">
 <!--Iterate over the sequence of names that we want to match on -->
 <xsl:for-each select="tokenize($csvString,',')">
  <!--Build the sequence(list) of matched items, 
      snagging the first one that matches each value -->
  <xsl:sequence select="$di:meta[matches(@domain
                       ,concat('.*('
                               ,current()
                               ,').*')
                       ,'i')][1]" />
 </xsl:for-each>
</xsl:variable>
<!--Return the first item in the sequence from matching on 
    the list of domain regex fragments -->
<xsl:value-of select="$matchedMetaSequence[1]" />

You could also put this into a custom function like this:

<xsl:function name="di:findMeta">
 <xsl:param name="meta" as="element()*" />
 <xsl:param name="names" as="xs:string" />

 <xsl:for-each select="tokenize(normalize-space($names),',')">
  <xsl:sequence select="$meta[matches(@domain
                                      ,concat('.*('
                                              ,current()
                                              ,').*')
                                      ,'i')][1]" />
 </xsl:for-each>
</xsl:function>

and then use it like this:

 <xsl:value-of select="di:findMeta($di:meta,'foo,bar,baz')[1]"/>
0

精彩评论

暂无评论...
验证码 换一张
取 消