Rajeev Ranjan
Rajeev Ranjan

Reputation: 13

Prevent xmlns=" " added to copy element using xslt

I have a XML file where i want to copy some element using XSLT, But it's adding xmlns=" " in copied element.

XSLT

<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:x="http://www.example.com/rsd/DataAccess" 
  exclude-result-prefixes="x"
>
  <xsl:output method="xml" indent="yes"/>

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

  <xsl:template match="x:Adapter[@Key='AuditLogging']">
    <xsl:copy-of select="."/>
    <Adapter Key="AutoExport"></Adapter>
  </xsl:template>
</xsl:stylesheet>

XML

 <Adapters xmlns="http://www.example.com/rsd/DataAccess">
   <Adapter Key="LASTCHANGEDATE" />
   <Adapter Key="AuditLogging" />
 </Adapters>

Output XML

<Adapters xmlns="http://www.example.com/rsd/DataAccess">
   <Adapter Key="LASTCHANGEDATE" />
   <Adapter Key="AuditLogging" />
   <Adapter Key="AutoExport" xmlns="" />
</Adapters>

How to prevent adding xmlns=" " in element.

Upvotes: 1

Views: 2211

Answers (2)

Tim C
Tim C

Reputation: 70618

This is because in your input XML, all the elements belong to a namespace

<Adapters xmlns="http://www.example.com/rsd/DataAccess">

However, when you create the new Adapter element in your template, like so...

<Adapter Key="AutoExport">

You are actually creating a new element that does not belong to any namespace, and so the output has the xmlns='' present to indicate this.

One solution is to declare a default namespace in your XSLT, so that any unprefixed elements you create in your XSLT will then be part of this namespace.

Try this XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
  xmlns:x="http://www.example.com/rsd/DataAccess"  
  xmlns="http://www.example.com/rsd/DataAccess" exclude-result-prefixes="x">

<xsl:output method="xml" indent="yes"/>

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

<xsl:template match="x:Adapter[@Key='AuditLogging']">
   <xsl:copy-of select="."/>
    <Adapter Key="AutoExport" />
 </xsl:template>
</xsl:stylesheet>

Upvotes: 5

Piotr Stapp
Piotr Stapp

Reputation: 19820

The problem is that below declaration in XSL

<xsl:template match="x:Adapter[@Key='AuditLogging']">
   <xsl:copy-of select="."/>
    <Adapter Key="AutoExport">
    </Adapter>
 </xsl:template>

Creates new element in different xml namespace than root element (which has defined xmlns="http://www.example.com/rsd/DataAccess")

The easiest method is to declare proper namespace in new element, but not all XSL compilers will remove it.

You can try also suggestion from Define a default namespace for use in XSL XPaths with xpath-default-namespace but I don't know which version are using

Upvotes: 0

Related Questions