xsl-list
[Top] [All Lists]

RE: Getting rid of xmlns="" attributes

2003-12-30 19:34:10
If I understand you right, the source XML elements have no
namespace, and you want the result XML elements to be in no
namespace. However,

I need
to add two namespaces to the XML.

I take this to mean you want to add two namespace
declarations to the output,
"http://tempuri.org/FormSchema.xsd";
and
"http://www.w3c.org/2001/XMLSchema-instance";

Clearly the desired prefix for the latter is "xsi",
and you've got that covered.
But what prefix do you want for the former? And what
elements do you want to be in that namespace?
In your stylesheet you're using the null prefix,
i.e. you're making "...tempuri.org..." the default namespace.

As a result, your output <template> element is in
this "...tempuri.org..." namespace (because result tree
elements with no namespace prefix go in the stylesheet's
default namespace). Is that what you wanted?
Did you want the other elements to be in that namespace too?

As you hinted at, xsl:copy-of copies the child elements
and preserves their namespaces, i.e. no namespace. So
the serializer has to add a declaration xmlns="" to the children
in order to override the xmlns="...tempuri.org..." on the parent.

If you want the child elements to be in the tempuri.org
namespace too, you'll need to use a modified identity transform
(as I wrote in a message on this list earlier today... is this
an FAQ?):

<?xml version="1.0" encoding="UTF-8"?>
<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"/>

  <xsl:template match="*" priority="3">
    <xsl:element name="{local-name()}"
                namespace="http://www.tempuri.org/...";>
      <xsl:apply-templates select="@*|node()" />
    </xsl:element>
  </xsl:template>

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


More interspersed below...


Erik Allen wrote:

      I've been using XSL for a few months now and I've been given a
request for a transformation of our XML document into another XML
document, with only some slight changes. One of the changes 
is to remove
a xml:space="preserve" attribute, but I consider that a 
trivial problem
that I can easily solve. (I'm just explicitly writing the element with
the two other attributes that appear.) The bigger problem is 
that I need
to add two namespaces to the XML.
      From what I've read on this list, the best place to do something
like that is to place the namespace definitions within the
<xsl:stylesheet> element. I've done that, but now all the 
child elements
have xmlns="" appearing within them. My XSL looks like this:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
                      xmlns="http://tempuri.org/FormSchema.xsd";
      
xmlns:xsi="http://www.w3c.org/2001/XMLSchema-instance";
                      version = '1.0'>

<xsl:output method="xml"/>

<xsl:template match="/template">
      <template>
              <xsl:attribute name="version">
                      <xsl:value-of select="@version"/>
              </xsl:attribute>
              <xsl:attribute name="readVersion">
                      <xsl:value-of select="@readVersion"/>
              </xsl:attribute>
              <xsl:copy-of select="*"/>
      </template>
</xsl:template>

</xsl:stylesheet>

      The transformation appears to work fine, except, as I said, the
child elements of the root <template> element, all have the attribute
xmlns="". A short snippet of it would be this:

<?xml version="1.0" encoding="utf-8"?>
<template xmlns="http://tempuri.org/FormSchema.xsd";
xmlns:xsi="http://www.w3c.org/2001/XMLSchema-instance"; version="3"
readVersion="3">
  <exportTimeStamp xmlns="">
    <date>2003-12-29</date>
    <time>15:31:34</time>
  </exportTimeStamp>
  <templateInfo xmlns="" name="" id="1139410602" revision="1">
    
  </templateInfo>
  ...
</template>

      I've found that if I change the namespace in the
<xsl:stylesheet> from xmlns to xmlns:y, then I don't get the rogue
attribute,

That makes sense. You no longer have a non-null default namespace,
so there is no need to override the default namespace to produce
elements that are in no namespace.

but that is also giving me the incorrect namespace.

Here is where I would need more specifics to understand what you want.
Which elements have the incorrect namespace and what namespace
did you want them to have?

(Terminology precision check ... do you mean the namespace is incorrect,
or a namespace declaration, or a namespace prefix?)

Do you want all of the output XML to be in no namespace? all
in the tempuri namespace? some of each?
If the latter, what namespace prefix do you want used for each?
You can't use "" as a prefix for two different namespaces,
unless you put xmlns="..." in multiple places.

The
source XML does not have any namespaces defined within it, and I think
that I read somewhere that the <xsl:copy-of> might have issues with
that. 
      Is there anyway to get the namespaces to come out correctly,
without giving me the xmlns=""?

      Erik Allen


Hope this helps,
Lars


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list