これは、IDテンプレートに基づいて構築することで実行できます。まず、 Receiver要素と一致するテンプレートが必要です。それをコピーしますが、同時にname属性を追加します。
<xsl:template match="Receiver">
<Receiver name="{name}">
<xsl:apply-templates select="@*|node()"/>
</Receiver>
</xsl:template>
item要素に対して同様のことを行うことができます。これが「属性値テンプレート」を使用して、name要素の値からname属性を作成する方法に注意してください。
次に、名前に一致するテンプレートが必要であり、要素は必要ありません。それらは無視されるため、出力されません。
<xsl:template match="name|no" />
これが完全なXSLTです
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="Receiver">
<Receiver name="{name}">
<xsl:apply-templates select="@*|node()"/>
</Receiver>
</xsl:template>
<xsl:template match="item">
<item no="{no}">
<xsl:apply-templates select="@*|node()"/>
</item>
</xsl:template>
<xsl:template match="name|no" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XMLに適用すると、次のように出力されます
<Message>
<Receiver name="123">
<address>111</address>
<phone>1000</phone>
</Receiver>
<List>
<item no="1">
<desc>one</desc>
</item>
<item no="2">
<desc>two</desc>
</item>
</List>
</Message>
ここで、より一般的なものにしたい場合で、親要素の最初の「leaf」要素を属性に変換するルールがある場合は、このXSLTを試してください。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*[*[1][not(*)]]">
<xsl:copy>
<xsl:attribute name="{name(*[1])}">
<xsl:value-of select="*"/>
</xsl:attribute>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*/*[1][not(*)]"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
これも同じ結果を出力するはずです。それがどのように機能するかを読者に練習として残しておきます。