一部の例外を除いて、ほとんどの要素がそのままコピーされるように変換する必要があるドキュメントがあります。特定の指定されたノードでは、子要素を追加する必要があり、これらの子要素の一部は、ソースドキュメント。別の「モデル/横断歩道」xml ファイルには、追加する要素が含まれています。ソース文書を参照する必要があるクロスウォーク内の要素には、特定の要素を指す「ソース」属性があります。もちろん、私の実際のソース ドキュメント (および実際の横断歩道) は、これらの例よりも複雑で多様です。
ソース ドキュメントの例を次に示します。
<?xml version="1.0" encoding="UTF-8"?>
<root>
<album>
<artist>Frank Sinatra</artist>
<title>Greatest Hits</title>
</album>
<album>
<artist>Miles Davis</artist>
<title>Kind Of Blue</title>
</album>
<movie>
<title>ET</title>
<director>Steven Spielberg</director>
</movie>
<movie>
<title>Blues Brothers</title>
<director>John Landis</director>
</movie>
</root>
「横断歩道」(crswlk.xml)は次のとおりです。
<?xml version="1.0" encoding="UTF-8"?>
<root>
<album>
<artist-info>
<artist2 source="artist"/>
</artist-info>
</album>
<movie>
<director-info>
<director2 source="director"/>
</director-info>
</movie>
</root>
そして、ここに目的の出力があります:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<album>
<artist>Frank Sinatra</artist>
<title>Greatest Hits</title>
<artist-info>
<artist2>Frank Sinatra</artist2>
</artist-info>
</album>
<album>
<artist>Miles Davis</artist>
<title>Kind Of Blue</title>
<artist-info>
<artist2>Miles Davis</artist2>
</artist-info>
</album>
<movie>
<title>ET</title>
<director>Steven Spielberg</director>
<director-info>
<director2>Steven Spielberg</director2>
</director-info>
</movie>
<movie>
<title>Blues Brothers</title>
<director>John Landis</director>
<director-info>
<director2>John Landis</director2>
</director-info>
</movie>
</root>
これが私のxsltです:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="crosswalk" select="document('crswlk.xml')"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*/album|movie">
<xsl:variable name="theNode" select="."/>
<xsl:variable name="nodeName" select="name()"/>
<xsl:element name="{$nodeName}">
<xsl:apply-templates select="@* | node()"/>
<xsl:apply-templates select="$crosswalk//*[name()=$nodeName]/*">
<xsl:with-param name="curNode" select="$theNode"/>
</xsl:apply-templates>
</xsl:element>
</xsl:template>
<xsl:template match="*[@source]">
<xsl:param name="curNode" />
<xsl:variable name="sourceNodeName" select="@source"/>
<xsl:element name="{name()}">
<xsl:value-of select="$curNode//*[name()=$sourceNodeName]"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
$curNode
これは、最後のテンプレートが初めてアクセスを試みると処理を停止します。Eclipse (Xalan 2.7.1) で xslt を実行すると、次のエラーがスローされます。
ソース ドキュメントのノードと一致するテンプレートに同様のノードセットをパラメーターとして渡すと、期待どおりに機能します。ノードセットにアクセスできます。ただし、ノードセットを上記の最後のテンプレートに渡すことはできません。テンプレートが外部ドキュメントのノードと一致するためですか? きっとわからない。この点にたどり着くまでにしばらく時間がかかりました。ありがとう!