XSLT copying all nodes from a source

How to copy all xsl nodes (with hierarchy)

This scenario could be used in case we need to append more nodes at the end of the xml doccument. Sample input :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="utf-8" ?>
<root>
  <header>
    <ha>some value</ha>
    <hb>another value</hb>
  </header>
  <content>
    <rec>
      <ra>1</ra>
      <rb>name 1</rb>
      <rc>address 1</rc>
      <rd>100</rd>
    </rec>
    <rec>
      <ra>2</ra>
      <rb>name 2</rb>
      <rc>address 2</rc>
      <rd>200</rd>
    </rec>
    <rec>
      <ra>3</ra>
      <rb>name 3</rb>
      <rc>address 3</rc>
      <rd>300</rd>
    </rec>
  </content>
  <footer>
    <fa>some footer</fa>  
  </footer>
</root>

Just copying everything :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:xs="http://www.w3.org/2001/XMLSchema"
	xmlns:math="http://www.w3.org/2005/xpath-functions/math"
	xmlns:map="http://www.w3.org/2005/xpath-functions/map"
	xmlns:array="http://www.w3.org/2005/xpath-functions/array"
	exclude-result-prefixes="#all"
	version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="/">
        <xsl:apply-templates/>
  </xsl:template>
  
</xsl:stylesheet>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:xs="http://www.w3.org/2001/XMLSchema"
	xmlns:math="http://www.w3.org/2005/xpath-functions/math"
	xmlns:map="http://www.w3.org/2005/xpath-functions/map"
	xmlns:array="http://www.w3.org/2005/xpath-functions/array"
	exclude-result-prefixes="#all"
	version="3.0">
  <xsl:output omit-xml-declaration="yes" method="xml" indent="yes"/>

  <xsl:template match="/root">
    <MyList>
      <xsl:apply-templates select="@*|node()" mode="copy" />
    </MyList>
  </xsl:template>
  
    <xsl:template match="@*|node()" mode="copy">
    <!-- copying  all nodes recursively-->
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates mode="copy" />
    </xsl:copy>
  </xsl:template>
  
</xsl:stylesheet>

Result :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<MyList>
   <header>
      <ha>some value</ha>
      <hb>another value</hb>
   </header>
   <content>
      <rec>
         <ra>1</ra>
         <rb>name 1</rb>
         <rc>address 1</rc>
         <rd>100</rd>
      </rec>
      <rec>
         <ra>2</ra>
         <rb>name 2</rb>
         <rc>address 2</rc>
         <rd>200</rd>
      </rec>
      <rec>
         <ra>3</ra>
         <rb>name 3</rb>
         <rc>address 3</rc>
         <rd>300</rd>
      </rec>
   </content>
   <footer>
      <fa>some footer</fa>
   </footer>
</MyList>

How to copy all xsl nodes but a specific one

Let’s remove the header node :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:xs="http://www.w3.org/2001/XMLSchema"
	xmlns:math="http://www.w3.org/2005/xpath-functions/math"
	xmlns:map="http://www.w3.org/2005/xpath-functions/map"
	xmlns:array="http://www.w3.org/2005/xpath-functions/array"
	exclude-result-prefixes="#all"
	version="3.0">
  <xsl:output omit-xml-declaration="yes" method="xml" indent="yes"/>

  <xsl:template match="/root">
    <MyList>
      <xsl:apply-templates select="@*|node()" mode="copy" />
    </MyList>
  </xsl:template>
  
    <xsl:template match="@*|node()" mode="copy">

    <!-- We  dont  want  the  header  andd footer nodes-->
    <xsl:if test="name()!='header'">
    <!-- copying  all nodes recursively-->
      <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates mode="copy" />
      </xsl:copy>
    </xsl:if>
  </xsl:template>
  
</xsl:stylesheet>

Result :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<MyList>
   <content>
      <rec>
         <ra>1</ra>
         <rb>name 1</rb>
         <rc>address 1</rc>
         <rd>100</rd>
      </rec>
      <rec>
         <ra>2</ra>
         <rb>name 2</rb>
         <rc>address 2</rc>
         <rd>200</rd>
      </rec>
      <rec>
         <ra>3</ra>
         <rb>name 3</rb>
         <rc>address 3</rc>
         <rd>300</rd>
      </rec>
   </content>
   <footer>
      <fa>some footer</fa>
   </footer>
</MyList>

How to copy all nodes and insert a new node

Now let’s add an email address before the node .

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:xs="http://www.w3.org/2001/XMLSchema"
	xmlns:math="http://www.w3.org/2005/xpath-functions/math"
	xmlns:map="http://www.w3.org/2005/xpath-functions/map"
	xmlns:array="http://www.w3.org/2005/xpath-functions/array"
	exclude-result-prefixes="#all"
	version="3.0">
  <xsl:output omit-xml-declaration="yes" method="xml" indent="yes"/>

  <xsl:template match="/root">
    <MyList>
      <xsl:apply-templates select="[(@*|node())]" mode="copy" />
    </MyList>
  </xsl:template>
  
  <xsl:template match="@*|node()" mode="copy">
  
    <!-- adding a new node email befoore noooode rc -->
    <xsl:if test="name()='rc'">
      <email><xsl:value-of select="translate(../rb,' ','')" />@somemail.net</email>
    </xsl:if>
      
      <!-- We  dont  want  the  header  andd footer nodes-->
    <xsl:if test="name()!='header'">
      <!-- copying  all nodes recursively-->
      <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates mode="copy" />
      </xsl:copy>
    </xsl:if>
  </xsl:template>
  
</xsl:stylesheet>

Result :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<MyList>
   <content>
      <rec>
         <ra>1</ra>
         <rb>name 1 </rb>
         <email>[email protected]</email>
         <rc>address 1</rc>
         <rd>100</rd>
      </rec>
      <rec>
         <ra>2</ra>
         <rb>name 2</rb>
         <email>[email protected]</email>
         <rc>address 2</rc>
         <rd>200</rd>
      </rec>
      <rec>
         <ra>3</ra>
         <rb>name 3</rb>
         <email>[email protected]</email>
         <rc>address 3</rc>
         <rd>300</rd>
      </rec>
   </content>
   <footer>
      <fa>some footer</fa>
   </footer>
</MyList>

How to copy all xml values and encapsulate them between double quotes

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
  <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
    </xsl:template>
    <xsl:template match="*[not(*)]">
      <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:text>"</xsl:text>
        <xsl:apply-templates/>
        <xsl:text>"</xsl:text>
     </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Result:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="UTF-8"?><root>
  <header>
    <ha>"some value"</ha>
    <hb>"another value"</hb>
  </header>
  <content>
    <rec>
      <ra>"1"</ra>
      <rb>"name 1 "</rb>
      <rc>"address 1"</rc>
      <rd>"100"</rd>
    </rec>
    <rec>
      <ra>"2"</ra>
      <rb>"name 2"</rb>
      <rc>"address 2"</rc>
      <rd>"200"</rd>
    </rec>
    <rec>
      <ra>"3"</ra>
      <rb>"name 3"</rb>
      <rc>"address 3"</rc>
      <rd>"300"</rd>
    </rec>
  </content>
  <footer>
    <fa>"some footer"</fa>  
  </footer>
</root>