Use XSLT to transform a child node but leave the rest intact

xml, xslt

Solution

What you want is the identity transform.

Your template that has the comment `Whenever you match any node or any attribute` isn't doing what you think. It's only matching the root element.

Also, you're stripping all `text()` nodes with that last template.

Here's an example of what you should do:

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <!--Identity Transform.-->
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="AA2/foo">
        <RenamedAA2>
            <xsl:copy>
                <xsl:apply-templates select="node()|@*"/>
            </xsl:copy>
        </RenamedAA2>
    </xsl:template>

    <xsl:template match="AA2">
        <xsl:apply-templates/>
    </xsl:template>

</xsl:stylesheet>

XML Output

<root>
   <parentHeader/>
   <body>
      <ChildAA>
         <AA1>
            <foo>bar</foo>
            <foo>bar2</foo>
         </AA1>
         <RenamedAA2>
            <foo>bar</foo>
         </RenamedAA2>
         <RenamedAA2>
            <foo>bar2</foo>
         </RenamedAA2>
      </ChildAA>
      <ChildBB>
         <BB1>
            <foo>bar</foo>
            <foo>bar2</foo>
         </BB1>
         <BB2>
            <foo>bar</foo>
            <foo>bar2</foo>
         </BB2>
      </ChildBB>
   </body>
</root>

Problem

I have a XML where I only want to modify a specific section, and leave the rest intact, how can this be done? i.e I only want to modify the node AA2 ``` <root> <parentHeader> </parentHeader> <body> <ChildAA> <AA1> <foo>bar</foo> <foo>bar2</foo> </AA1> <AA2> <foo>bar</foo> <foo>bar2</foo> </AA2> </ChildAA> <ChildBB> <BB1> <foo>bar</foo> <foo>bar2</foo> </BB1> <BB2> <foo>bar</foo> <foo>bar2</foo> </BB2> </ChildBB> </body> </root> ``` I have the following XSLT which only returns the modified section. How can I include everything else? ``` <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="*"/> <!-- Whenever you match any node or any attribute --> <xsl:template match="/*"> <xsl:apply-templates/> </xsl:template> <xsl:template match="AA2"> <RenamedAA2> <xsl:copy-of select="."/> </RenamedAA2> </xsl:template> <xsl:template match="text()"/> </xsl:stylesheet> ``` I am looking for something like this as result ``` <root> <parentHeader> </parentHeader> <body> <ChildAA> <AA1> <foo>bar</foo> <foo>bar2</foo> </AA1> <RenamedAA2> <foo>bar</foo> </RenamedAA2> <RenamedAA2> <foo>bar2</foo> </RenamedAA2> </ChildAA> <ChildBB> <BB1> <foo>bar</foo> <foo>bar2</foo> </BB1> <BB2> <foo>bar</foo> <foo>bar2</foo> </BB2> </ChildBB> </body> </root> ```

Original source