XML an identical copy using XSLT

K

kluge.wolfram

Hi,

i get stucked on a transformation problem using XSLT. What i need is
to copy an XML Tree to an output XML without any automatic changes.
Since i used <xsl:copy> or <xsl:copy-of> there occur unwanted side
effects.
For example i just copied a xml were several namespace declarations
are present more than one time. Then
the transformation do remove the declaration at the child nodes.
Another funny automatism is - if i remove a node
which holds a namespace declaration the first child is inheriting its
declaration.

Thank you for your support,

Im looking forward to hearing from yoou soon.

Wolfram
 
M

Martin Honnen

i get stucked on a transformation problem using XSLT. What i need is
to copy an XML Tree to an output XML without any automatic changes.
Since i used <xsl:copy> or <xsl:copy-of> there occur unwanted side
effects.
For example i just copied a xml were several namespace declarations
are present more than one time. Then
the transformation do remove the declaration at the child nodes.
Another funny automatism is - if i remove a node
which holds a namespace declaration the first child is inheriting its
declaration.

If you have e.g.
<foo xmlns="http://example.com/2008/ns1">
<bar>
<baz/>
</bar>
</foo>
then all three elements are in the namespace
http://example.com/2008/ns1. Consequently if you copy the bar element
without its foo parent then the serializer has to add a xmlns
declaration to make sure the copied element is still in its namespace.

In the XSLT/XPath 1.0 data model there are namespace nodes which are in
scope for element nodes. And xsl:copy http://www.w3.org/TR/xslt#copying
copies these namespace nodes.
With XSLT 2.0 http://www.w3.org/TR/xslt20/#shallow-copy you can specify
whether namespaces are copied but for the namespace of the element
itself that would not prevent the copying of its namespace. If you want
to strip the namespace of an element then you can't use xsl:copy,
instead you need to create a new element e.g.

<xsl:template match="pf1:bar"
xmlns:pf1="http://example.com/2008/ns1">

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

</xsl:template>
 
K

kluge.wolfram

If you have e.g.
   <foo xmlns="http://example.com/2008/ns1">
     <bar>
       <baz/>
     </bar>
   </foo>
then all three elements are in the namespacehttp://example.com/2008/ns1. Consequently if you copy the bar element
without its foo parent then the serializer has to add a xmlns
declaration to make sure the copied element is still in its namespace.

In the XSLT/XPath 1.0 data model there are namespace nodes which are in
scope for element nodes. And xsl:copyhttp://www.w3.org/TR/xslt#copying
copies these namespace nodes.
With XSLT 2.0http://www.w3.org/TR/xslt20/#shallow-copyyou can specify
whether namespaces are copied but for the namespace of the element
itself that would not prevent the copying of its namespace. If you want
to strip the namespace of an element then you can't use xsl:copy,
instead you need to create a new element e.g.

   <xsl:template match="pf1:bar"
     xmlns:pf1="http://example.com/2008/ns1">

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

   </xsl:template>

What i want is the following,

<ds:foo xmlns:ds="http://example.com/2008/ns1">
<ds:bar>
<ds:baz/>
</ds:bar>
</ds:foo>

if i copy the node list ds:bar and ignore <ds:foo> then ds:bar gets
the declaration of foo.

<ds:bar xmlns:ds="http://example.com/2008/ns1">
<ds:baz/>
</ds:bar>

this is unwanted and i would like to omit this.

second behavior is ....

<ds:foo xmlns:ds="http://example.com/2008/ns1">
<ds:bar xmlns:ds="http://example.com/2008/ns1>
<ds:baz/>
</ds:bar>
</ds:foo>

and i copy the hole structure the result looks like shown below

<ds:foo xmlns:ds="http://example.com/2008/ns1">
<ds:bar>
<ds:baz/>
</ds:bar>
</ds:foo>

but this arent the exact copies of there sources.

Thank You for Help

Wolfram
 
M

Martin Honnen

What i want is the following,

<ds:foo xmlns:ds="http://example.com/2008/ns1">
<ds:bar>
<ds:baz/>
</ds:bar>
</ds:foo>

if i copy the node list ds:bar and ignore <ds:foo> then ds:bar gets
the declaration of foo.

<ds:bar xmlns:ds="http://example.com/2008/ns1">
<ds:baz/>
</ds:bar>

this is unwanted and i would like to omit this.

What exactly do you want to omit? As said, if you want to strip the
namespace of an element node then use
<xsl:template match="ds:*"
xmlns:ds="http://example.com/2008/ns1">

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

but this arent the exact copies of there sources.

XSLT does not work with the source code, it works on the XSLT/XPath data
model.
 
K

kluge.wolfram

What happens if you try the following? which is actually
equivalent as far as the __expanded__ namespaces are
concerned:

<ds:foo xmlns:ds="http://example.com/2008/ns1">
  <xyz:bar xmlns:xyz="http://example.com/2008/ns1>
        <ds:baz/>
  </xyz:bar>
</ds:foo>










- Zitierten Text anzeigen -

Hi Ken

this works
<ds:foo xmlns:ds="http://example.com/2008/ns1">
<xyz:bar xmlns:xyz="http://example.com/2008/ns1>
<ds:baz/>
</xyz:bar>
</ds:foo>

i think the reason why it works it the new namspace prefix.
But what is going on if redundant namespace declarations occurs.

Thanks

Wolfram
 
K

Ken Starks

Hi Ken

this works


i think the reason why it works it the new namspace prefix.
But what is going on if redundant namespace declarations occurs.

Thanks

Wolfram

I believe the xslt processor is allowed to do its own
thing, in the case of redundant namespaces, but
I can't say I've read the specifications and seen
it in black and white.
 

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

Forum statistics

Threads
473,996
Messages
2,570,237
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top