2

一部の例外を除いて、ほとんどの要素がそのままコピーされるように変換する必要があるドキュメントがあります。特定の指定されたノードでは、子要素を追加する必要があり、これらの子要素の一部は、ソースドキュメント。別の「モデル/横断歩道」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 を実行すると、次のエラーがスローされます。

ソース ドキュメントのノードと一致するテンプレートに同様のノードセットをパラメーターとして渡すと、期待どおりに機能します。ノードセットにアクセスできます。ただし、ノードセットを上記の最後のテンプレートに渡すことはできません。テンプレートが外部ドキュメントのノードと一致するためですか? きっとわからない。この点にたどり着くまでにしばらく時間がかかりました。ありがとう!

4

2 に答える 2