The use xsl:key attribute is the path relative to the matched element, so you probably want to
<xsl:key name="parKey" match="ns3:pkey" use="../@id"/>
to group pkey elements using the id attribute of their parent reply element.
But overall, your /input pattern is suspicious:
<xsl:template match="/input"> <xsl:variable name="output_186" select="ns3:output"/> <xsl:copy> <xsl:copy-of copy-namespaces="no" select="./@*" /> <xsl:copy-of select=" * except $output_186"></xsl:copy-of> </xsl:copy> </xsl:template>
This is just copying the entire source input element (minus ns3:output ), it does not apply templates recursively, so the nodeA template that deals with pkey will never fire.
Try something else like this:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns3="http://mysample.org" exclude-result-prefixes="xsl"> <xsl:strip-space elements="*" /> <xsl:output omit-xml-declaration="no" indent="yes" /> <xsl:key name="parKey" match="ns3:pkey" use="../@id"/> <xsl:template match="@*|node()"> <xsl:copy copy-namespaces="no"> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:template> <xsl:template match="ns3:output" /> <xsl:template match="nodeA"> <xsl:copy copy-namespaces="no"> <xsl:apply-templates select="@*|node()" /> <xsl:element name="pkey"> <xsl:value-of select="key('parKey', @id)" /> </xsl:element> </xsl:copy> </xsl:template> </xsl:stylesheet>
source share