我正在尝试创建一个动态“匹配”元素的 xslt 函数。在函数中,我将传递两个参数 - item()* 和一个逗号分隔的字符串。我在 select 语句中标记逗号分隔的字符串<xsl:for-each>
,然后执行以下操作:
select="concat('$di:meta[matches(@domain,''', current(), ''')][1]')"
而不是选择语句“执行”xquery,它只是返回字符串。
我怎样才能让它执行 xquery?
提前致谢!
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]"/>