10

私はXSLTに取り組んでおり、次のように実装する必要があります。私のソースXMLサンプルは次のようになります。

<?xml version="1.0" encoding="ISO-8859-1"?>
    <catalog>
        <cd>
            <title>A</title>  
            <title>B</title>
            <title>C</title>  
        </cd>
    </catalog>

いくつかのキーと値のペアのリストがあると考えてください。

    Key         Value
    A           Algebra
    B           Biology
    C           Chemistry
    D           Data Analysis
    ---         ---

    ----        ---

キー「A」が出現するたびに適切な値に置き換える必要があるように、xsltを作成する必要があります。

また、同じXSLT内のキーと値のペアのリストについても言及する必要があります。サンプル出力:

<Data>
    <Subject>Algebra</Subject>
    <Subject>Biology</Subject>
    <Subject>Chemistry</Subject>
 </Data>

誰かがそれを行う方法を私に手伝ってもらえますか?

ありがとうございました。

4

1 に答える 1

16

I. シンプルな XSLT 1.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:codes>
   <code key="A" value="Algebra"/>
   <code key="B" value="Biology"/>
   <code key="C" value="Chemistry"/>
   <code key="D" value="Data Analysis"/>
 </my:codes>

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

 <xsl:template match=
  "title/text()[. = document('')/*/my:codes/*/@key]">

  <xsl:value-of select=
   "document('')/*/my:codes/*[@key=current()]/@value"/>
 </xsl:template>
</xsl:stylesheet>

提供された XML ドキュメントに適用した場合:

<catalog>
    <cd>
        <title>A</title>
        <title>B</title>
        <title>C</title>
    </cd>
</catalog>

必要な正しい結果が生成されます

<catalog>
   <cd>
      <title>Algebra</title>
      <title>Biology</title>
      <title>Chemistry</title>
   </cd>
</catalog>

説明:

xsl:stylesheetこれは、xsl 名前空間とは異なる (空でない) 名前空間に属するグローバル要素 ( の子要素) としてインライン XML ノードを含める標準的な方法です。


Ⅱ.keys を使用した、より効率的な XSLT 1.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:codes>
       <code key="A" value="Algebra"/>
       <code key="B" value="Biology"/>
       <code key="C" value="Chemistry"/>
       <code key="D" value="Data Analysis"/>
     </my:codes>

     <xsl:key name="kCodeByName" match="code" use="@key"/>

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

     <xsl:template match=
      "title/text()[. = document('')/*/my:codes/*/@key]">

      <xsl:variable name="vCur" select="."/>

      <xsl:for-each select="document('')">
          <xsl:value-of select=
           "key('kCodeByName', $vCur)/@value"/>
      </xsl:for-each>
     </xsl:template>
</xsl:stylesheet>

この変換が同じ XML ドキュメント (上記) に適用されると、同じ正しい、必要な結果が生成されます。

<catalog>
   <cd>
      <title value="Algebra"/>
      <title value="Biology"/>
      <title value="Chemistry"/>
   </cd>
</catalog>

説明:

関数を介したデータへのアクセスkey()は、通常、サブリニア (多くの場合 O(1)) であり、線形検索よりも非常に高速です (これは、検索するノードの数が多い場合に重要です)。

xsl:key検索対象のノードを含むドキュメントが現在のドキュメントである場合、別のドキュメントのノードを処理しながら、インデックス ( ) を介して 1 つのドキュメントのノードにアクセスできます。他のドキュメントからノードにアクセスするには、そのルート (または関心のあるノードを保存して、変数から参照する必要があります)。


III. XSLT 2.0 ソリューション:

<xsl:stylesheet version="2.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="*"/>

 <xsl:variable name="vCodes">
  <codes>
   <code key="A" value="Algebra"/>
   <code key="B" value="Biology"/>
   <code key="C" value="Chemistry"/>
   <code key="D" value="Data Analysis"/>
  </codes>
 </xsl:variable>

 <xsl:key name="kCodeByName" match="code" use="string(@key)"/>

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

 <xsl:template match=
  "title/text()[key('kCodeByName', ., $vCodes)]">

  <xsl:sequence select=
   "key('kCodeByName', ., $vCodes)/@value"/>
 </xsl:template>
</xsl:stylesheet>

この変換が同じ XML ドキュメント (上記) に適用されると、同じ正しい、必要な結果が生成されます。

<catalog>
   <cd>
      <title value="Algebra"/>
      <title value="Biology"/>
      <title value="Chemistry"/>
   </cd>
</catalog>

説明:

効率的な XSLT 1.0 ソリューションとほぼ同じですが、次の点が異なります。

  1. XSLT 2.0 では、テンプレート マッチ パターンに変数参照を含めることができます。

  2. XSLT 2.0 では、現在のドキュメントとインデックス付きドキュメントを操作するアクロバティックなトリックは必要ありません。key()関数の 3 番目の引数は、インデックスを使用するツリーを指定することです。

于 2012-06-18T04:46:07.157 に答える