[XSL] Changing namespace definition

I

insane79

Hi,

i have one problem with an xsl trasformation (I'm using Xalan)

The source XML document is the following:

<?xml version = '1.0' encoding = 'ISO-8859-1'?>
<ROOT xmlns:NAME='old_namespace'>
<NAME:element>...</NAME:element>
<NAME:element>...</NAME:element>
</ROOT>

What i want is to change the uri of the namespace from
"old_namespace" to "new_namespace".

To achive this goal i've wrote this document:

<?xml version="1.0" encoding="iso-8859-1"?>

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

<xsl:template match = "/">
<xsl:element name = "ROOT">
<xsl:attribute name = "xmlns:NAME">new_namespace</xsl:attribute>
<xsl:copy-of select="/ROOT/NAME:element" />
</xsl:element>
</xsl:template>

</xsl:styleshee>

And the result of the transformation is:

<?xml version="1.0" encoding="UTF-8"?>
<ROOT xmlns:NAME="new_namespace">
<NAME:element xmlns:NAME="old_namespace">...</NAME:element>
<NAME:element xmlns:NAME="old_namespace">...</NAME:element>
</ROOT>

The namespace definition in the root element is changed
but the processor have put the old namespace definition
in every child of the root.

The result that i expected is

<?xml version="1.0" encoding="UTF-8"?>
<ROOT xmlns:NAME="new_namespace">
<NAME:element>...</NAME:element>
<NAME:element>...</NAME:element>
</ROOT>

I hope that the explanation of the problem was clear.

Thanks
 
R

Richard Tobin

What i want is to change the uri of the namespace from
"old_namespace" to "new_namespace".

You can't just change the declaration on the top-level element: the
elements will still be in the old namespace and XSLT will generate
declarations to make sure they are.

You need a template that copies each element by creating a new element
with the same local name but the new namespace name. You can modify
the usual identity transform to do this.

-- Richard
 
I

insane79

You need a template that copies each element by creating a new element
with the same local name but the new namespace name. You can modify
the usual identity transform to do this.

I'm not sure if i understand in the right way, honwever
i've wrote the following document

<?xml version="1.0" encoding="iso-8859-1"?>

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

<xsl:eek:utput
method="xml"
version="1.0"
encoding="ISO-8859-1" />

<xsl:template match = "/">
<xsl:apply-templates />
</xsl:template>

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

<xsl:template match="@xmlns:NAME" >
<xsl:apply-templates />
</xsl:template>

<xsl:template match="ROOT" >
<xsl:element name="ROOT">
<xsl:attribute name="xmlns:NAME">
<xsl:text>new_namespace</xsl:text>
</xsl:attribute>
<xsl:apply-templates />
</xsl:element>
</xsl:template>

<xsl:template match="NAME:element" >
<xsl:element name="NAME:element">
<xsl:attribute name="xmlns:NAME">
<xsl:text>new_namespace</xsl:text>
</xsl:attribute>
<xsl:copy>
<xsl:apply-templates select="@*"/>
</xsl:copy>
</xsl:element>
</xsl:template>

</xsl:stylesheet>

But the resutlt is the same of before: the old namespace
declaration is put into every child of ROOT.

Where i'm doing the wrong thing?
-- Richard

Bye
Roberto
 
B

Ben Edgington

But the resutlt is the same of before: the old namespace
declaration is put into every child of ROOT.

Where i'm doing the wrong thing?

See my reply earlier today to Chris Bedford in the thread "how to get
the identity transformation to stop outputting extra 'xmlns:' attrib
?" in this group. It tells you what you need to know.

Ben
 
R

Richard Tobin

insane79 said:
<xsl:attribute name="xmlns:NAME">

You're still trying to change the namespace declarations (which you
can't: they're not part of the XPath data model), instead of the
elements themselves. You need something like this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:eek:ld="http://example.org/old">

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

<xsl:template match="old:*">
<xsl:element name="{local-name()}" namespace="http://example.org/new">
<xsl:apply-templates select="node()"/>
</xsl:element>
</xsl:template>

</xsl:stylesheet>

-- Richard
 
I

insane79

See my reply earlier today to Chris Bedford in the thread "how to get
the identity transformation to stop outputting extra 'xmlns:' attrib
?" in this group. It tells you what you need to know.

Thanks for the hint, i've tried both your solution and the one from Chris
but without any good result.

I can change the namespace in the root node but the old namespace is still
applied to every child.

Bye
Roberto
 
I

insane79

Hi,
i have one problem with an xsl trasformation (I'm using Xalan)

[CUT]

I've solved the problem (with your help) and i post thee solution
in the hope that can be usefull for somebody.

The xslt document is the following:

<?xml version="1.0" encoding="iso-8859-1"?>

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

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

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

<xsl:template match="ROOT">
<xsl:element name="ROOT">
<xsl:attribute name="xmlns:NAME">http://example.org/new</xsl:attribute>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>

</xsl:stylesheet>

If you put in input an XML like this:

<?xml version = '1.0' encoding = 'ISO-8859-1'?>
<ROOT xmlns:NAME='old_namespace'>
<NAME:element attr1="xxx" >
<NAME:subElement attr2="yyy">abcdefghi</NAME:subElement>
</NAME:element>
<NAME:element attr1="xxx" >
<NAME:subElement attr2="yyy">abcdefghi</NAME:subElement>
</NAME:element>
</ROOT>

The output will be the following


<?xml version="1.0" encoding="ISO-8859-1"?>
<ROOT xmlns:NAME="http://example.org/new">
<NAME:element attr1="xxx">
<NAME:subElement attr2="yyy">abcdefghi</NAME:subElement>
</NAME:element>
<NAME:element attr1="xxx">
<NAME:subElement attr2="yyy">abcdefghi</NAME:subElement>
</NAME:element>
</ROOT>

So only the namespace declaration in the root element is changed

Many for your help

Bye
Roberto
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top