2012-01-17 12 views
2

での繰り返しの使用:私は、次のXSLT持っているXSLT

<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="node()[child::node() 
      [contains(@Source, 'filename1') 
      or contains(@Source, 'filename2')]]" /> 

することは誰もが私がfilemanesをループする代わりに、「ファイル名1」と「ファイル名2」のパラメータまたは変数を使用する方法を私に助言することはできますか?

は、どのように2番目のテンプレートは、(新しいテンプレートを追加すると、おそらく?)に書き換えることができるように

<xsl:variable name="FileName"> 
    <name>filename1</name> 
    <name>filename2</name> 
    </xsl:variable> 

として、インラインXSLを使用するには事前のおかげで、

レオ

+0

あなたが本当にここにcontains()を必要としているのだろうか?私は、contains =を使用すると "="が行うことがよくある間違いであるので尋ねます。その場合、答えは 'match =" * [*/@ Source = $ FileName/name] "となります。" –

答えて

0

I. XSLT 1.0のソリューション(これはXSLT 2.0の方が簡単です):

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<my:fileNames> 
    <f>filename1</f> 
    <f>filename2</f> 
</my:fileNames> 

<xsl:variable name="vFilenames" 
       select="document('')/*/my:fileNames/*"/> 

<xsl:template match="node()|@*" name="identity" priority="-1"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="node()"> 
    <xsl:variable name="vCur" select="."/> 
    <xsl:variable name="vHit"> 
    <xsl:for-each select="$vFilenames"> 
    <xsl:if test= 
    "$vCur/node()[contains(@Source, current())]">1</xsl:if> 
    </xsl:for-each> 
    </xsl:variable> 
    <xsl:choose> 
    <xsl:when test="not(string-length($vHit))"> 
    <xsl:call-template name="identity"/> 
    </xsl:when> 
    </xsl:choose> 
</xsl:template> 
</xsl:stylesheet> 

(あなたは、人々は、あなたのソースXML ???提供する方法を学習します)、このXMLドキュメントに適用:

<t> 
    <tt> 
     <x> 
     <y/> 
     </x> 
     <v-v> 
     <p Source="filename3"> 
      <u/> 
      <v/> 
     </p> 
     </v-v> 
    </tt> 
</t> 

<t> 
    <tt> 
     <x> 
      <y/> 
     </x> 
     <mm> 
      <z Source="filename1"> 
       <u/> 
       <v/> 
      </z> 
     </mm> 
     <rr> 
      <m Source="filename2"> 
       <u/> 
       <v/> 
      </m> 
     </rr> 
     <v-v> 
      <p Source="filename3"> 
       <u/> 
       <v/> 
      </p> 
     </v-v> 
    </tt> 
</t> 

を指名手配、正しい結果を生成します


II。 XSLT 2.0ソリューション:この変換は、(上記のように)同じXML文書に適用され

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="pFileNames"> 
    <f>filename1</f> 
    <f>filename2</f> 
</xsl:param> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match= 
    "node()[node() 
      [some $fn in $pFileNames/f 
      satisfies 
       contains(@Source, $fn) 
      ] 
     ]"/> 
</xsl:stylesheet> 

、同じ正しい結果がを生産している:あなたは、あなたのXMLソースを示していない

<t> 
    <tt> 
     <x> 
     <y/> 
     </x> 
     <v-v> 
     <p Source="filename3"> 
      <u/> 
      <v/> 
     </p> 
     </v-v> 
    </tt> 
</t> 
+0

本当にありがとうございました。サンプルのXMLファイルは私のニーズに合っています。現在、私はXSLT 1.0を使用する必要があります。この理由から、マイケルの推薦は私の仕事に直接当てはまらないようです。もう1つの制限は、私はドキュメントファンクションを使用できないということです。 Dimitresの変数定義をテンプレート内にcontains()を意図的に使用しました。しかし、他のケースでは "="を使用することも重要なので、私はこのケースの解決策にも非常に興味があります – Leo68

+0

Hello Dimitreもちろん、この回答を受け入れることを確認したいと思います。このウェブサイトのどこかでこの確認をしなければなりませんか?私の前のコメントでは、 "contains"の代わりに "="を使用すると、テンプレート仕様に関する推奨事項をあなたとMichaelに尋ねました。対応するアプローチを概説することができれば、それは私にとって非常に役に立ちます。 Thanks and regatrds、Leo – Leo68

+0

@ Leo68:はい、この回答の横にある「チェックマーク」をクリックすると、回答を受け入れます。 'contains()' vs '='に関しては、前者はもっと弛緩し、後者はより厳しくなります。 '$ String'のどこにでもある' $ Pattren'という文字列が '$ String' *に含まれているときに' contains($ String、$ Pattern) 'は' true() 'を評価します。一方、 '='は '$ String'が' $ Pattern'と正確に(文字列と文字で)等しいことを要求します。 'contains()'に似た2つの関数が存在します: 'starts-with()'と(XPath 2.0では) 'ends-with()'です。パターンが文字列のどこにあるのかわからないときは 'contains()'を使ってください –

関連する問題