属性の違い (新しい属性ノードではなく更新のみ) について 2 つの XML ドキュメントを比較し、属性と属性の新しい値への XPath ポインターのセットを生成するコードがあります。
セットアップ
たとえば、古い XML と新しい XML があるとします。
古い XML
<EntityA>
<EntityB id="foo1" value="bar1" ignoredbutsave="bazz1"/>
</EntityA>
新しい XML
<EntityA>
<EntityB id="foo2" value="bar2"/>
</EntityA>
私のコードは戻ります
/EntityA/EntityB/@id, foo2
/EntityA/EntityB/@value, bar2
古い XML を新しい XML にマージする XSLT を生成して、次の XML を作成したいと考えています。
<EntityA>
<EntityB id="foo2" value="bar2" ignoredbutsave="bazz1"/>
</EntityA>
SOで見つけたすべての回答は、属性名に関する事前の知識を前提としています。この場合、名前自体ではなく、属性の XPath 参照のみが与えられます。XPath 文字列を解析して属性名を取得できることはわかっていますが、その複雑さをコードから除外したいと考えています。
私が試したこと
古い XML から属性をコピーする必要があるため、属性値テンプレートを使用できません。ignoredbutsave
次のように、xsl:param を使用して XPath から属性名を選択し、xsl:attribute 内で使用しようとしました。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/EntityA/EntityB/@id">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<xsl:param name="newValue" select="name(/EntityA/EntityB/@id)"/>
<xsl:attribute name="$newValue">newAttributeId</xsl:attribute>
</xsl:copy>
</xsl:template>
<xsl:template match="/EntityA/EntityB/@value">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<xsl:param name="myattrname" select="name(/EntityA/EntityB/@value)"/>
<xsl:attribute name="$myattrname">newAttributeValue</xsl:attribute>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
ただし、これによりエラーが発生しますThe value '$myattrname' of the attribute 'name' is not a valid QName.
属性の XPath とその属性の新しい値が与えられた場合、属性名を明示的に参照せずにその値を更新する XSLT を生成するにはどうすればよいでしょうか?