6

Saxon 9.1.0.7 を使用して簡単な外部ルックアップを機能させようとして、髪の毛の残りを引っ張っています。

私は単純なソースファイル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" 値に基づいて "Genre" 値を取得することです。

したがって、私の 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>

...


私が抱えている問題は、何も返ってこないことです。私は現在ちょうど得ます

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

以前は GenreMapping の子要素として、テンプレート match="GetGenreMappingObjectsResponse" を入力するたびに、すべての GenreMapping (DepartmentCode、DepartmentName、Genre) からすべてのテキストを出力するだけでした。

私は一生、自分が間違っていることを理解することはできません。ヘルプ/提案は大歓迎です。

現在の実際の 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 です (したがって、正しいルックアップ ファイルが開かれます。Type は、現在使用していないが使用する予定の名前です。

4

2 に答える 2

9

XSLT 2.0 では、やりたいことができる方法が 2 つあります。

1 つは、関数の 3 つのパラメーター バージョンですkey。3 番目のパラメーターを使用すると、キーを機能させたいルート ノードを指定できます (デフォルトでは、常にメイン ドキュメントのルートです)。

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

もう 1 つの方法は、ノードkeyの下で関数を使用することです。$lookupDoc

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

これらのメソッドは両方とも、キーに関する XSLT 2.0 仕様で文書化されており、XSLT 1.0 では機能しません。

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

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

あはは!問題は、select="$lookupDoc"呼び出しapply-templatesで、期待するものではなくデフォルトのテンプレートを呼び出しているため、パラメーターが失われていることです。

これを次のように変更します。

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

これにより、テンプレートが適切に呼び出され、キーが機能するはずです。

したがって、最終的な XSLT シートは次のようになります。

  <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>
于 2009-08-14T13:50:50.753 に答える
0

わかりました、これは少し精神的なものであり、私はそれを理解しているとは主張していませんが、うまくいきます (ソフトウェアのキャリアのように聞こえます)。

私が抱えていた問題は、apply-templates を呼び出して外部ドキュメントを変数として渡すと、「Genremapping」と呼ばれるテンプレートでさえ、どのテンプレートにも一致しなかったことです。

そのため、ワイルドカードを使用してそれをキャッチし、apply-templates を呼び出すときにも、興味のある子になるようにノード セットを絞り込みました。それでも、「GenreMapping」と呼んだテンプレートには決して入りませんでしたが、代わりに「*」テンプレートにのみ移動することを選択しました。

これが意味することは、私の新しいテンプレート マッチがそこにあるすべての単一の 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>

郵便番号で答えます。助けてくれてありがとう

于 2009-08-14T17:04:06.260 に答える