Вот (почти то же самое, что и раньше) короткое решение :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kFollowingChild1" match="*[not(self::Child1)]/*"
use="generate-id(../preceding-sibling::Child1[1])"/>
<xsl:template match="Parent">
<TransformedXML>
<xsl:apply-templates/>
</TransformedXML>
</xsl:template>
<xsl:template match="Child1">
<Child>
<xsl:for-each select="*|key('kFollowingChild1', generate-id())">
<xsl:attribute name="attribute{position()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
</Child>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
когда это преобразование применяется к предоставленному документу XML :
<Root>
<Parent>
<Child1><Node1>AAA</Node1><Node2>BBB</Node2></Child1>
<Child2><NodeX>XXX</NodeX><NodeY>YYY</NodeY></Child2>
<Child1><Node1>EEE</Node1><Node2>FFF</Node2></Child1>
<Child2><NodeX>GGG</NodeX><NodeY>HHH</NodeY></Child2>
<OtherChild></OtherChild>
</Parent>
</Root>
желаемый, правильный результат получается :
<TransformedXML>
<Child attribute1="AAA" attribute2="BBB" attribute3="XXX" attribute4="YYY"/>
<Child attribute1="EEE" attribute2="FFF" attribute3="GGG" attribute4="HHH"/>
</TransformedXML>