XSLT中的动态“匹配”语句

时间:2011-05-18 12:07:09

标签: xslt-2.0 concat

我正在尝试创建一个动态“匹配”元素的xslt函数。在函数中,我将传递两个参数 - item()*和逗号分隔的字符串。我在<xsl:for-each> select语句中对逗号分隔的字符串进行了标记,然后执行以下操作:

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

而不是select语句'执行'xquery,它只是返回字符串。

如何让它执行xquery?

提前致谢!

1 个答案:

答案 0 :(得分:1)

问题是你在concat()函数中包含了过多的表达式。在进行求值时,它返回一个字符串,该字符串将是XPath表达式,而不是计算使用REGEX匹配表达式的动态字符串的XPath表达式。

您想要使用:

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

虽然,由于您现在分别评估每个术语,而不是将每个术语放在单个正则表达式模式中并选择第一个术语,现在它将返回每个匹配的第一个结果,而不是第一个结果来自匹配项目的序列。这可能是也可能不是你想要的。

如果您想要匹配项目序列中的第一项,您可以执行以下操作:

<!--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]" />

你也可以把它放到这样的自定义函数中:

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

然后像这样使用它:

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