2009-08-14 19 views
5

私はSaxon 9.1.0.7を使用して簡単な外部ルックアップを取得しようとしています。XSLT 2.0 key()とdocument()を使用した外部ルックアップ

私は、単純なソースファイルdummy.xmlあります

<something> 
    <monkey> 
     <genrecode>AAA</genrecode> 
    </monkey> 
    <monkey> 
     <genrecode>BBB</genrecode> 
    </monkey> 
    <monkey> 
     <genrecode>ZZZ</genrecode> 
    </monkey> 
    <monkey> 
     <genrecode>ZER</genrecode> 
    </monkey> 
</something> 

を次にルックアップファイルは、GenreSet_124.xmlです:

私は「何
<GetGenreMappingObjectsResponse> 
    <tuple> 
     <old> 
     <GenreMapping DepartmentCode="AAA" 
         DepartmentName="AND - NEWS AND CURRENT AFFAIRS" 
         Genre="10 - NEWS"/> 
     </old> 
    </tuple> 
    <tuple> 
     <old> 
     <GenreMapping DepartmentCode="BBB" 
         DepartmentName="AND - NEWS AND CURRENT AFFAIRS" 
         Genre="11 - NEWS"/> 
     </old> 
    </tuple> 

    ... lots more 
</GetGenreMappingObjectsResponse> 

達成しようとしているのは単に「ジャンル"DepartmentCode"値に基づく値。

ようなので、私のXSLに見えます:私が持っている問題は、私は戻って何も得ることである

... 
<!-- Set up the genre lookup key --> 
<xsl:key name="genre-lookup" match="GenreMapping" use="@DepartmentCode"/> 


<xsl:variable name="lookupDoc" select="document('GenreSet_124.xml')"/> 

<xsl:template match="/something"> 
<stuff> 
    <xsl:for-each select="monkey"> 
     <Genre> 

     <xsl:apply-templates select="$lookupDoc"> 
     <xsl:with-param name="curr-label" select="genrecode"/> 
     </xsl:apply-templates> 

     </Genre> 
    </xsl:for-each> 
</stuff> 
</xsl:template> 

<xsl:template match="GetGenreMappingObjectsResponse"> 
    <xsl:param name="curr-genrecode"/> 

    <xsl:value-of select="key('genre-lookup', $curr-genrecode)/@Genre"/> 

</xsl:template> 

...


。私は現在、ちょうど私がテンプレートマッチ=「GetGenreMappingObjectsResponse」を入力したときに、それだけですべてのGenreMappingからすべてのテキストをプリントアウトするだろう、私は以前にGenreMappingの子要素として、GenreMappingの属性であることを、すべての検索データを移動した

<?xml version="1.0" encoding="UTF-8"?> 
<stuff> 
    <Genre/> 
    <Genre/> 
    <Genre/> 
    <Genre/> 
</stuff> 

を取得します(DepartmentCode、DepartmentName、Genre)!

私の人生にとって私は間違っていることを理解できません。どんなhelpo/suggestionsも大変ありがとうございます。

は現在の実際のXSLTのリストを見つけるしてください:。

<?xml version="1.0"?> 
<xsl:stylesheet version="2.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

<!-- Define the global parameters --> 
<xsl:param name="TransformationID"/> 
<xsl:param name="TransformationType"/> 

<!-- Specify that XML is the desired output type --> 
<xsl:output method="xml" encoding="UTF-8" indent="yes"/> 

<!-- Set up the genre matching capability --> 
<xsl:key name="genre-lookup" match="GenreMapping" use="@DepartmentCode"/> 

<xsl:variable name="documentPath"><xsl:value-of select="concat('GenreSet_',$TransformationID,'.xml')"/></xsl:variable> 
<xsl:variable name="lookupDoc" select="document($documentPath)"/> 

<!-- Start the first match on the Root level --> 
<xsl:template match="/something"> 
<stuff> 
    <xsl:for-each select="monkey"> 
     <Genre> 
     <xsl:apply-templates select="$lookupDoc/*"> 
     <xsl:with-param name="curr-genrecode" select="string(genrecode)"/> 
     </xsl:apply-templates> 
     </Genre> 
    </xsl:for-each> 
</stuff> 
</xsl:template > 

<xsl:template match="GetGenreMappingObjectsResponse"> 
    <xsl:param name="curr-genrecode"/> 
    <xsl:value-of select="key('genre-lookup', $curr-genrecode, $lookupDoc)/@Genre"/> 
</xsl:template> 
</xsl:stylesheet> 

TransformationIDがなかれ124である(したがって、正しいルックアップファイルが開かれたのタイプは、私が現在使用してそれに意図するものではないのです名前だけです

。 XSLT 2.0で
+0

どのXSLTコンパイラを使用していますか? – Welbog

+0

Saxon-B 9.1.0.7 –

+0

図。私はそれに慣れていない。たぶん後でTomalakがあなたを助けてくれるでしょう。キーレス法は機能していますか? – Welbog

答えて

7

あなたがやりたいことができる2つの方法があります:

一つはkey機能の3パラメータバージョンである第三のパラメータは、あなたがキーが上で動作するようにしたいルートノードを指定することができます(。デフォルトでは常にメイン文書のルート):

<xsl:value-of select="key('genre-lookup', $curr-genrecode,$lookupDoc)/@Genre"/> 

もう一つの方法は、$lookupDocノードの下key機能を使用することです:

<xsl:value-of select="$lookupDoc/key('genre-lookup', $curr-genrecode)/@Genre"/> 

これらのメソッドの両方がXSLT 2.0 specification on keysで文書化し、しませんされていますXSLT 1.0で動作します。

XSLT 1.0に制限されている場合は、キーを使用しないようにこれを書き直す必要があります。

<xsl:value-of select="$lookupDoc//GenreMapping[@DepartmentCode = $curr-genrecode]/@Genre"/> 

なるほど!apply-templatesの呼び出しで、のselect="$lookupDoc"がデフォルトのテンプレートを呼び出しているため、パラメータが失われてしまいます。これに

変更を:

<xsl:apply-templates select="$lookupDoc/*"> 
    <xsl:with-param name="curr-genrecode" select="string(genrecode)"/> 
</xsl:apply-templates> 

正しくテンプレートを呼び出しますし、キーは動作するはずです。 (

<xsl:variable name="lookupDoc" select="document('XMLFile2.xml')"/> 
    <xsl:key name="genre-lookup" match="GenreMapping" use="@DepartmentCode"/> 
    <xsl:template match="/something"> 
    <stuff> 
     <xsl:for-each select="monkey"> 
     <Genre> 
      <xsl:apply-templates select="$lookupDoc/*"> 
      <xsl:with-param name="curr-genrecode" select="string(genrecode)"/> 
      </xsl:apply-templates> 
     </Genre> 
     </xsl:for-each> 
    </stuff> 
    </xsl:template> 
    <xsl:template match="GetGenreMappingObjectsResponse"> 
    <xsl:param name="curr-genrecode"/> 
    <xsl:value-of select="key('genre-lookup',$curr-genrecode,$lookupDoc)/@Genre"/> 
    </xsl:template> 

Source of information

+0

こんにちは、 お返事ありがとうございます。 私はすでにこれらの両方を試しています(マスターテンプレート内からこのフォームを使用してapply-templateを呼び出すことはありません)。両方とも何も返しません。私はまだ空の要素を得ますか? 鍵の設定に間違っていることがありますか? について –

+0

これはXSLTコンパイラの特有の問題かもしれませんが、 '$ lookupDoc/*'を使用すると、あなたのベースをカバーする必要があります。 – Welbog

+0

こんにちは、もう一度、 私はもはや空の要素を得る私は空白(24行の価値)でいっぱいになる更新されたコードを使用してください。 私は本当に困惑しています。 –

0

OK、これは少し精神であり、私はそれを理解していると主張していないが、それは動作します:

ので、最終的なXSLTシートは次のようになります。ソフトウェアのキャリアのように聞こえる)。

私が問題を抱えていたのは、apply-templatesを呼び出して外部文書を変数として渡すと、「Genremapping」と呼ばれるテンプレートでも一致しないということでした。

これをキャッチするためにワイルドカードを使用しました。また、apply-templatesを呼び出すときに、私が興味を持った子になるようにノードのセットを絞りました。これはノードの名前を印刷することができました。 「GenreMapping」を参照してください。しかし、「GenreMapping」と呼ばれていたテンプレートには、「*」テンプレートだけを選択することはありませんでした。

これは、1つのGenreMappingノードごとに新しいテンプレートの一致が呼び出されるということです。そのため、少し効率が悪い可能性があります。私がしなければならなかったことは、述語が一致した場合に印刷を行うことでした。

だから、今、この(何もキーが一切使用されていない)のようになります。これは、出力のすべての

... 
<xsl:template match="/something"> 
<stuff> 
    <xsl:for-each select="monkey"> 
     <Genre> 
     <key_value><xsl:value-of select="genrecode"/></key_value> 
     <xsl:variable name="key_val"><xsl:value-of select="genrecode"/></xsl:variable> 
     <code> 
     <xsl:apply-templates select="$lookupDoc/*/*/*/*"> 
     <xsl:with-param name="curr-genrecode" select="string(genrecode)"/> 
     </xsl:apply-templates> 

     </code> 
     </Genre> 
    </xsl:for-each> 
</stuff> 
</xsl:template > 


<xsl:template match="*"> 
    <xsl:param name="curr-genrecode"/> 
    <xsl:value-of select=".[@DepartmentCode = $curr-genrecode]/@Genre"/> 
</xsl:template> 
... 

:で一致がないとして 注意、最後KEY_VALUEが正しくコード入力を持っていません検索ドキュメント。

<?xml version="1.0" encoding="UTF-8"?> 
<stuff xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <Genre> 
     <key_value>AAA</key_value> 
     <code>10 - NEWS</code> 
    </Genre> 
    <Genre> 
     <key_value>AAA</key_value> 
     <code>10 - NEWS</code> 
    </Genre> 
    <Genre> 
     <key_value>BBB</key_value> 
     <code>11 - NEWS</code> 
    </Genre> 
    <Genre> 
     <key_value>SVVS</key_value> 
     <code/> 
    </Genre> 
</stuff> 

郵便番号の回答。 Welbogに助けてくれてありがとう。

+0

奇妙なことにもかかわらず、実用的なソリューションを見つけられたらうれしいです。 – Welbog

関連する問題