[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: question about identity transform

Subject: Re: question about identity transform
From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx>
Date: Thu, 2 Nov 2006 11:05:56 -0800
attribute node after the children
To add a new angle to this interesting topic:

If you would refers it, and make it, say: ` node ( ) | @* ' the nodes
would first be copied, resulting in the attributes ending up illegally:
you may not create an attribute node after you create an element node in
the result tree.

We already discussed why the above statement is not true.


In XPath 2.0, however one could use the "," operator and we could have
the following identity rule:


<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"


<xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="node() | @*"> <xsl:copy> <xsl:apply-templates select="@*,node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>

Now, if one reverses the order of the arguments of the "," operator like this:


<xsl:apply-templates select="node(), @*"/>


and the source xml document happens to have attributes, then there
will be indeed a runtime error to the effect that an attribute node
cannot be created after the children of its containing element.

The moral is always to know when we are using sets and when sequences
and to be very cautious when using sequences as they are a very
different beasts from sets, although might seem quite similar.


-- Cheers, Dimitre Novatchev --------------------------------------- Truly great madness cannot be achieved without significant intelligence. --------------------------------------- To invent, you need a good imagination and a pile of junk ------------------------------------- You've achieved success in your field when you don't know whether what you're doing is work or play




On 10/31/06, Abel Braaksma <abel.online@xxxxxxxxx> wrote:
Bill French wrote:
>
> I've used the identity transform many times to do useful things and
> have often wondered about the match pattern. Why is the match pattern
>
> "node() | @*"
>
> rather than simply "node()"? Aren't attributes returned by node()?

Node( ) matches attributes, but it defaults to the child axis, so the
above is actually:

"child::node( ) | attribute::*"

The order of the match pattern is important. The identity-pattern looks
in full as follows (implementations vary):

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

Chopped into pieces:

<xsl:template match="node(  ) | @*">
Order is not important here. I tend to consider the `|' operation an
"or" operation, it helps my understanding (in fact, I believe it works
the same way as the union, later). All it says: if the input tree has a
node(), go here, if it has an attribute, go here too.

What is important in this declaration is that it must be as generic as
possible. Because the template matching rules always give precedence to
a more specific match, this very generic template will always be
overriden whenever you declare something more specific, like a node-name
or an attribute name.

<xsl:copy>
Copy the node. In effect, this means, it will *only* copy the node and
not its descendants or attributes. It will, however, copy the namespace,
if any. You could consider using <xsl:copy-of />, but that would change
the identity template rather drastically and will not allow you to
override any nodes or attributes by just declaring a more specific template.

<xsl:apply-templates select="@* | node(  )"/>
This, ultimately, says: "take all current attributes, and find any
declared templates for these attributes. When done, take all descendant
nodes, along the child-axis, and find any declaraed templates for these
nodes. " The `|' operator is the union operator and combines both node sets.

What is tricky here is that node( ) on itself can match anything. But
when used in an select expression, it can only select items along its
child axis (I peeked, it's detailed in XPath 2.0 programmer's reference
page 280). The attribute-axis is never on the child-axis. As such, you
will need to specify the items on the attribute-axis explicitly.

If you would refers it, and make it, say: ` node ( ) | @* ' the nodes
would first be copied, resulting in the attributes ending up illegally:
you may not create an attribute node after you create an element node in
the result tree. However, I'm not sure if this is really enforced by the
specs.


I hope I got the bits and pieces right (no doubt someone will correct me if otherwise) and that it clears things up a bit for you.

Cheers,
-- Abel Braaksma
  http://www.nuntia.com

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.