Проблема в том, что вы переносите слишком большую часть выражения в функцию concat()
. Когда это оценивается, он возвращает строку, которая будет выражением XPath, а не оценивает выражение XPath, которое использует динамическую строку для выражения соответствия REGEX.
Вы хотите использовать:
<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]"/>
person
Mads Hansen
schedule
18.05.2011