Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old October 20th, 2005, 03:33 AM
Authorized User
 
Join Date: Sep 2004
Posts: 36
Thanks: 0
Thanked 0 Times in 0 Posts
Default Problem copying XML nodes

I've got an XML document that has a SOAP wrapper around it:

<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <SOAP-ENV:Body>
        <FirstNode>
            <SecondNode>
                <Children />
            </SecondNode>
        </FirstNode>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

I'd like to use XSL to copy the <SecondNode> and all the <Children> and remove the SOAP wrapper to create a new XML document.

I've tried this:

<xsl:template match="//FirstNode/node()">
        <NewFirstNode>
            <xsl:copy-of select="."/>
        </NewFirstNode>
</xsl:template>

But it puts the namespace on the <SecondNode> like this:

<SecondNode xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

Any ideas why? I'd appreciate any tips. Thanks.

 
Old October 20th, 2005, 09:03 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

xsl:copy-of is defined to copy all the in-scope namespaces of the element being copied, because the XSLT processor has no way of knowing which of them might be needed (by prefix-sensitive element or attribute content).

XSLT 2.0 has an option copy-namespaces="no" designed explicitly for this use case.

In 1.0 you need a variant of the identity template that copies elements without their namespaces:

<xsl:template match="*">
  <xsl:element name="{name()}" namespace="{namespace-uri()}">
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates/>
  </
</

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old October 20th, 2005, 09:39 AM
Authorized User
 
Join Date: Sep 2004
Posts: 36
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks for the reply. Would I replace what I have above with this?

<xsl:template match="//FirstNode/node()">
        <NewFirstNode>
            <xsl:element name="{name()}" namespace="{namespace-uri()}">
                <xsl:copy-of select="@*" />
                <xsl:apply-templates />
            </xsl:element>
        </NewFirstNode>
</xsl:template>

At present this returns an empty FirstNode with no children elements.


 
Old October 20th, 2005, 10:26 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

No, use the code exactly as written, and replace

<xsl:template match="//FirstNode/node()">
        <NewFirstNode>
            <xsl:copy-of select="."/>
        </NewFirstNode>
</xsl:template>

with

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

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old October 21st, 2005, 04:48 AM
Authorized User
 
Join Date: Sep 2004
Posts: 36
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I tried that but it still copies the whole source document and leaves the namespace on the 1st element.

Here's my third attempt which I think is very close:

<xsl:template match="*[not(namespace-uri())]">
    <xsl:element name="{local-name(.)}">
        <xsl:copy-of select="@*[local-name() != 'xmlns']" />
        <xsl:apply-templates />
    </xsl:element>
</xsl:template>
<xsl:template match="/">
    <NewFirstNode>
       <xsl:apply-templates select="//FirstNode/SecondNode/node()" />
    </NewFirstNode>
</xsl:template>

This give me the exact structure that i'm after and all the child nodes are present. The only issue is that none of the data is present in the transformed XML.

Is there anything obvious that might be preventing this?

 
Old October 21st, 2005, 09:04 AM
Authorized User
 
Join Date: Sep 2004
Posts: 36
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hi Mike,

On page 196 of the WROX XSLT 2nd Edition Programmer's Reference <xsl:copy-of > is defined.

Under the Content heading it says, "None; the element is always empty"

Does this mean what I am trying to achieve above is not possible? i.e. I won't be able to get the element and children element values in my transformed XML.

Cheers,
Francis

 
Old October 21st, 2005, 09:48 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

No, what that is saying is that you can't write things like

<xsl:copy-of select="xyz">
  <something-here/>
</xsl:copy-of>

It's not saying that any elements written to the result tree will be empty - on the contrary, they will be exact copies of the elements you are copying.

However, here you don't want an exact copy. You want a copy of the tree minus its namespaces. Remember that in the tree model which XSLT sees, every namespace declaration is effectively copied to every element that it applies to, and you want to copy the tree without these namespaces. The way to do that is the way you were shown in a previous reply.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old October 21st, 2005, 09:55 AM
Authorized User
 
Join Date: Sep 2004
Posts: 36
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Unfortunately that didn't work.

 
Old October 21st, 2005, 10:25 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

I don't know why you're making such a meal of this. This stylesheet:

<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:strip-space elements="*"/>

<xsl:template match="*">
  <xsl:element name="{name()}" namespace="{namespace-uri()}">
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

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

</xsl:stylesheet>

applied to this document:

<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <SOAP-ENV:Body>
        <FirstNode>
            <SecondNode>
                <Children />
            </SecondNode>
        </FirstNode>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

produces this output:

<?xml version="1.0" encoding="UTF-8"?>
<SecondNode>
   <Children/>
</SecondNode>

Which part of it doesn't work?

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old October 21st, 2005, 10:37 AM
Authorized User
 
Join Date: Sep 2004
Posts: 36
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Mea culpa.

<xsl:template match="text()">

</xsl:template>

Was at the bottom of my stylesheet!!!

Thanks for your help.







Similar Threads
Thread Thread Starter Forum Replies Last Post
Copying DOCTYPE in input to the output xml mrame XSLT 3 July 31st, 2008 04:26 PM
copying xml attributes golddog XSLT 1 September 12th, 2007 01:05 PM
Problem Copying Nodes tclotworthy XSLT 14 February 13th, 2007 01:13 PM
Copying XML nodes from one document to another hughcr C# 2 May 12th, 2005 01:20 AM
Display nodes from xml nambati XSLT 2 September 17th, 2004 07:57 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.