2011-05-18 15 views
1

要素に対して動的に「一致」するxslt関数を作成しようとしています。この関数では、item()*とコンマで区切られた文字列の2つのパラメータを渡します。私は<xsl:for-each> select文でカンマ区切りの文字列をトークン化し、次の操作を行います。その代わりXQueryは、それだけで文字列を返して「実行」を選択文のXSLTの動的な 'matches'ステートメント

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

xqueryを実行するにはどうすればよいですか?

ありがとうございます!

答えて

1

問題は、concat()関数で式の値を大量に折り返してしまうことです。それが評価されると、REGEX一致式の動的文字列を使用するXPath式を評価するのではなく、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]"/> 
+0

ありがとう!それは働いた –

関連する問題