問題1。
最初の問題については、キーを使用できます。
<xsl:key name="variable-key" match="//variable" use="@name" />
そのキーは、名前を使用して、ドキュメント内のすべての可変要素にインデックスを付けます。したがって、次の XPath 式を使用して、これらの要素にアクセスできます。
key('variable-key', 'X')
このアプローチは、可変要素が多い場合に効率的です。
注: 各変数に独自のスコープがある場合 (つまり、ドキュメントの別の部分に表示されないローカル変数がある場合)、このアプローチは有効ではありません。その場合、このアプローチを変更する必要があります。
問題2。
属性のマッピングには、次のようなテンプレートを使用できます。
<xsl:template match="@baseType[. = 'int']">
<xsl:attribute name="baseType">
<xsl:value-of select="'Long'" />
</xsl:attribute>
</xsl:template>
この変換の意味は、baseType 属性を int 値と一致させるたびに、Long 値に置き換える必要があるということです。
この変換は、ドキュメント内の @baseType 属性ごとに行われます。
説明した戦略を使用すると、解決策は次のようになります。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<!-- Index all variable elements in the document by name -->
<xsl:key name="variable-key"
match="//variable"
use="@name" />
<!-- Just for demo -->
<xsl:template match="text()" />
<!-- Identity template: copy attributes by default -->
<xsl:template match="@*">
<xsl:copy>
<xsl:value-of select="." />
</xsl:copy>
</xsl:template>
<!-- Match the structure type -->
<xsl:template match="type[@baseType='structure']">
<Item>
<xsl:apply-templates select="*|@*" />
</Item>
</xsl:template>
<!-- Match the variable instance -->
<xsl:template match="variableInstance">
<Field>
<!-- Use the key to find the variable with the current name -->
<xsl:apply-templates select="@*|key('variable-key', @name)/@baseType" />
</Field>
</xsl:template>
<!-- Ignore attributes with baseType = 'structure' -->
<xsl:template match="@baseType[. = 'structure']" />
<!-- Change all baseType attributes with long values to an attribute
with the same name but with an int value -->
<xsl:template match="@baseType[. = 'int']">
<xsl:attribute name="baseType">
<xsl:value-of select="'Long'" />
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
このコードは、次の XML ドキュメントを変換します。
<!-- The code element is present just for demo -->
<code>
<variable baseType="int" name="X" />
<type baseType="structure" name="Y">
<variableInstance name="X" />
</type>
</code>
の中へ
<Item name="Y">
<Field baseType="Long" name="X"/>
</Item>