Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid all namespace occurrence in output by writing a single statement in XSLT

Tags:

xslt

I wrote "exclude-result-prefixes" and even then I see the name space occurrence appearance in output.

<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:simple="Simple name space"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:tcm="http://www.tridion.com/ContentManager/5.0"
    xmlns:xh="http://www.w3.org/1999/xhtml"
    xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:transform-ext="urn:tridion:transform-ext"
    xmlns="http://www.w3.org/1999/xhtml"
    exclude-result-prefixes="#default simple xh">

Actual Output

<strong xmlns="Simple name space">abcd
    <link xmlns="http://www.w3.org/1999/xhtml">
        <text>Header</text>
    </link>
</strong>

Is there any method so that I can exclude all namespace by writing single statement.

Here I explicitly mentioned

exclude-result-prefixes="#default simple xh"

How to avoid all namespace appearance in xslt?

like image 433
Patan Avatar asked Jun 25 '12 11:06

Patan


1 Answers

The exclude-result-prefixes attribute of xsl:stylesheet, when specified as "yes" mandates the removal of any namespace nodes of a litreral result element (only) that are inherited and don't define both the namespace-uri and prefix of the literal result element.

The following statement in the answer by Markus Jarderot is wrong:

"exclude-result-prefixes just removes the xmlns:foo="" attributes on the root tag of the result."

Here is a counter-example:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:z="z:z" exclude-result-prefixes="z">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
  <z:x xmlns:z="z:z">
   <z:y/>
  </z:x>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on any XML document (not used), the result is:

<z:x xmlns:z="z:z">
   <z:y/>
</z:x>

We see that:

  1. The namespace node (and definition) for the namespace with value (namespace-uri) "z:z" is not removed from the top element (what Markus Jarderot calls "root tag").

  2. The namespace with prefix "z" isn't removed from any literal element at all.

That shows the simple fact that specifying exclude-result-prefixes="yes" cannot remove a namespace if it isn't on an LRE (Literal Result Element) and even if a namespace node is on an LRE but is defining the namespace to which the element belongs.

In order to remove an element from the namespace it belongs to, or remove namespaces from non-LRE elements, we need to specify some additional processing.

One example is a replacement of the traditional identity rule with the following:

<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:template match="node()[not(self::*)]">
     <xsl:copy>
       <xsl:apply-templates/>
     </xsl:copy>
 </xsl:template>

 <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>

The above transformation replaces any element or attribute with a corresponding element or attribute that belongs to "no namespace". One potential use for it is to convert a document with a default namespace to a document without such.

For example, when applied on the following source XML document:

<z:x xmlns:z="z:z">
    <z:y z:attr="someValue"/>
</z:x>

the result of the transformation is:

<x>
   <y attr="someValue"/>
</x>

Finally a warning:

This transformation may be harmful if applied on documents that contains two elements (or two attributes) that have the same local name but belong to two different namespaces -- the transformation replaces these with elements (or attributes) that both belong to the same namespace (no namespace).

like image 55
Dimitre Novatchev Avatar answered Sep 19 '22 17:09

Dimitre Novatchev