Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get rid of xmlns="" (no-namespace) attribute in XSLT output

Tags:

xml

xslt

Here is my (simplified for this case scenario) XML:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="test_1.xsl" type="text/xsl"?>

<doc xmlns="http://www.foo.org">
  <div>
    <title>Mr. Title</title>
    <paragraph>This is one paragraph.
    </paragraph>
    <paragraph>Another paragraph.
    </paragraph>
  </div>
</doc>

And here is my XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:foo="http://www.foo.org">

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

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

 <xsl:template match="foo:doc">
  <xsl:element name="newdoc" namespace="http://www/w3.org/1999/xhtml">
   <xsl:apply-templates/>
  </xsl:element>
 </xsl:template>

 <xsl:template match="foo:div">
  <segment title="{foo:title}">
   <xsl:apply-templates/>
  </segment>
 </xsl:template>

 <xsl:template match="foo:title">
  <xsl:element name="h2">
   <xsl:apply-templates/>
  </xsl:element>
 </xsl:template>

 <xsl:template match="foo:paragraph">
  <xsl:element name="p">
   <xsl:apply-templates/>
  </xsl:element>
 </xsl:template>

</xsl:stylesheet>

The output produces this:

<newdoc xmlns="http://www/w3.org/1999/xhtml">
  <segment xmlns="" title="Mr. Title">
    <h2>Mr. Title</h2>
    <p>This is one paragraph.
    </p>
    <p>Another paragraph.
    </p>
  </segment>
</newdoc>

which is great, except for the xmlns="" in the segment element, that seems to be defining no namespace for itself and all of its children. How can I make it not add this?

Sidenote: I have also tried transforming the first node with

<xsl:template match="mydoc:doc">
  <html xmlns="http://www/w3.org/1999/xhtml">
   <xsl:apply-templates/>
  </html>
 </xsl:template>

instead, but it produces the same effect.

Thanks helpful people!

like image 823
Zori Avatar asked Apr 20 '11 04:04

Zori


People also ask

How remove all namespaces from XML in XSLT?

Example XSLT stylesheet that removes all namespaces insert into XMLTRANS (XSLID, XSLT) values ( 1, ' <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <!

What is namespace in XSLT?

The namespace name http://www.w3.org/1999/XSL/Transform is used primarily to identify elements which serve as declarations or instructions in the XSLT language.

What is the purpose of terminate attribute in XSL message?

The terminate attribute gives you the choice to either quit or continue the processing when an error occurs.

What is exclude result prefixes in XSLT?

The exclude-result-prefixes attribute in both XSLT 1.0 and XSLT 2.0 allows for the exclusion of certain namespace declarations in the output document.


2 Answers

It seems like you want to put all elements in the output document into the "http://www/w3.org/1999/xhtml" namespace. Currently you only specify the namespace for the "newdoc" element, all other elements are in the default namespace since there is no namespace declaration in your stylesheet. The nesting inside the stylesheet determines to which namespace the elements belong, not the nesting after the transformation.

You can declare the default namespace in your stylesheet to affect all otherwise unqualified elements:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:foo="http://www.foo.org"
    xmlns="http://www.w3.org/1999/xhtml">

Now you also no longer need the xsl:element tag and can directly use newdoc to create a element in the correct namespace.

like image 68
Jörn Horstmann Avatar answered Nov 13 '22 03:11

Jörn Horstmann


In the foo:div template, you create a segment element with the empty namespace. Since the parent element has a different namespace, the processor must add this namespace declaration.

If what you want is a segment with the same namespace than the parent, then use xsl:element instead:

<xsl:template match="foo:div">
    <xsl:element name="segment">
        <xsl:attribute name="title">
            <xsl:value-of select="foo:title"/>
        </xsl:attribute>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>
like image 31
Robert Bossy Avatar answered Nov 13 '22 03:11

Robert Bossy