2011-05-18 2 views
1

Я пытаюсь создать функцию xslt, которая динамически «соответствует» для элемента. В функции я передам два параметра - item() * и строку с разделителями-запятыми. Я разметить запятые разделителей строки в <xsl:for-each> операторе выбора, а затем выполните следующие действия:Оператор динамических «совпадений» в XSLT

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

Вместо выбор высказывания «исполняющее» XQuery, он просто возвращается строкой.

Как я могу заставить его выполнить xquery?

Заранее благодарен!

ответ

1

Проблема в том, что вы слишком сильно обертываете выражение в функции 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]"/> 
+0

спасибо! что сработало –

Смежные вопросы