Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NamesSpace removal from XSLT

Hi I am writing an XSLT and within that I am using <xsl:copy-of> function. Now when it's executed then namesapce from xml are also getting copied. In order to remove that I used function like <xsl:copy-of select="$RootNode/Child" copy-namespaces="no"/>. But If Child is having some more child elements then namespaces are appearing in that. So can anyone please tell me how can I remove that. Below is the snippet of my xslt and XML I am using.

<xsl:template match="/">
    <xsl:element name="Parent">
    <xsl:copy-of select="Child" copy-namespaces="no"/>
    </xsl:element>

And XML is:

<Child>
<GrandChild>
 <PhoneNumberType>DayPhone</PhoneNumberType>
</GrandChild></Child>

namespaces are not appearing in CustomerParty but they are present in Child but they are present in GrandChild.

like image 299
Kapil Avatar asked Dec 28 '22 22:12

Kapil


1 Answers

The copy-namespaces="no" attribute doesn't strip off all namespace nodes -- as noted in the XSLT 2.0 spec:

If it takes the value no, then none of the namespace nodes are copied: however, namespace nodes will still be created in the result tree as required by the namespace fixup process: see 5.7.3 Namespace Fixup. This attribute affects all elements copied by this instruction: both elements selected directly by the select expression, and elements that are descendants of nodes selected by the select expression.

Here is an example how to get rid of all the (non-mandatory) namespace nodes:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="*">
     <xsl:element name="{local-name()}">
       <xsl:apply-templates select="node()|@*"/>
     </xsl:element>
 </xsl:template>

 <xsl:template match="@*">
  <xsl:attribute name="{local-name()}">
   <xsl:value-of select="."/>
  </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

When this general transformation is applied on this XML document:

<x:nums xmlns:x="my:x">
  <x:num>01</x:num>
  <x:num>02</x:num>
  <x:num>03</x:num>
  <x:num>04</x:num>
  <x:num>05</x:num>
  <x:num>06</x:num>
  <x:num>07</x:num>
  <x:num>08</x:num>
  <x:num>09</x:num>
  <x:num>10</x:num>
</x:nums>

the wanted, correct result is produced:

<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>10</num>
</nums>

Do note:

  1. The transformation is not XSLT-2.0 - specific and can be used with XSLT 1.0, too.

  2. Removing all namespace nodes is generally an unsafe process, because nodes from different namespaces are all put in the "no namespace". In this process some attributes may be lost and the process is generally not reversible (not 1:1).

like image 77
Dimitre Novatchev Avatar answered Jan 01 '23 23:01

Dimitre Novatchev