xsl-list
[Top] [All Lists]

Re: [xsl] XSLT convert xml file to Excle Question III

2006-06-21 13:03:53
Karen,

Of course you're welcome: answering XSL questions is what the list is for. Also, we've seen exactly this kind of difficulty in the past, so that's not surprising. We also understand that many learners find themselves in "sub-optimal learning environments" -- like having to do expert work yesterday. In seven-going-on-eight years of XSLT we've seen it all, actually.

Available tutorials do help, as do the XSL FAQ, numerous articles for beginners and intermediates on XML.com, etc. But none of them can anticipate exactly your situation. This is why it's almost always a big help to start with a "lab" application designed to isolate you from the practical problems of the moment and thus direct attention to the language itself. Then you can build your mental model without having the extra overhead of applying it to your particular difficulty before you have it right. This is yet another reason why it's a problem to dive in when time is short and customers are waiting.

While you're asking:

"." in XPath is short for "self::node()". This has two parts:
self:: -- the specifier for the 'self' axis, traverses from a node to itself
node() -- the 'node()' node test, selects any node

Thus "self::node()" or "." is a traversal from any node to itself, and xsl:value-of select="." will write out the value of a node, no matter what kind of node it is.

Writing <xsl:apply-templates select="."/> will typically get you into one of those infinite loops you noticed -- see why? (I say "typically" because sometimes there are modes involved, which changes this.)

Also, you can see why J.Pietschmann knew you didn't need "*/." since that expands to "child::*/self::node()" -- it's just the same as plain "*", or for that matter the same as "*/./././." (which is like saying "go down one step and stand and stand and stand and stand").

Another application of self:: would be select="self::p" which traverses from a node to itself and selects it but *only if it's a p* (since other nodes don't match the node test "p").

Another application of node() would be select="node()" which is short for "child::node()", that is, select all the child nodes.

"/*" is short for "/child::*", which says to start at the root and select all child *elements* (of the root; there will only be one, the document element). Note this is different from "/node()", short for "/child::node()", which selects child nodes of the root, not only elements (the document element) but any comments or processing instructions that happen to be next to it. This way we have a way to deal with cases like this:

<?xml version="1.0"?>
<?karen?>
<!-- a comment -->
<doc>My document</doc>

/* will select only the doc element, whereas /node() will select the 'karen' PI, the comment and the element. (Note that the XML declaration is *not* a PI even though it looks just like one.)

XPath 1.0 has its tricks and complications, but can be learned comprehensively in only a few hours, if you have the good fortune of an experienced practitioner to guide you. Formal training really helps. It's much harder to pick up piecemeal.

Nevertheless if you Google for "XPath tutorial" you'll find a bunch of stuff....

Good luck,
Wendell


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--