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 ソリューションとほぼ同じですが、次の点が異なります。
XSLT 2.0 では、テンプレート マッチ パターンに変数参照を含めることができます。
XSLT 2.0 では、現在のドキュメントとインデックス付きドキュメントを操作するアクロバティックなトリックは必要ありません。key()
関数の 3 番目の引数は、インデックスを使用するツリーを指定することです。