Subject: RE: Traverse order From: Mike Brown <mbrown@xxxxxxxxxxxxx> Date: Tue, 17 Aug 1999 15:35:32 -0600 |
> When the XSL processor processes the XML document, it will > read the root element first, then the child elements. > Can we construct an XSL stylesheet to do the post-order > traverse, it print out the leaf element which has no > child, then the parents, and the last one is the root > element. Thank you for reposting this question with a new subject line. I do not have "the answer" but I can point you to some relevant portions of the working drafts: 1. What are child elements? http://www.w3.org/TR/xpath#element-nodes "The children of an element node are the element nodes, comment nodes, processing instruction nodes and text nodes for its content [...] The descendants of an element node are the children of the element node and the descendants of the element children nodes." 2a. How does an XSLT processor normally handle elements or the root node? http://www.w3.org/TR/WD-xslt#built-in-rule <xsl:template match="*|/"> <xsl:apply-templates/> </xsl:template> 2b. What does <xsl:apply-templates/> do? http://www.w3.org/TR/WD-xslt#section-Applying-Template-Rules "In the absence of a select attribute, the xsl:apply-templates instruction processes all of the children of the current node, including text nodes." [...] "A select attribute can be used to process nodes selected by an expression instead of all children. The value of the select attribute is an expression. The expression must evaluate to a node-set. The selected set of nodes is processed in document order, unless a sorting specification is present" So, <xsl:apply-templates/> is the same as <xsl:apply-templates select="*|comment()|processing-instruction()|text()"/> So now you can see where the behavior of an XSLT processor to recursively descend the tree is specified. It is in the built-in rule for elements and the root node, and the default behavior of <xsl:apply-templates/>. What you want to do is override these things. You're going to start at the root node whether you like it or not. So first override the template for the root node, and jump right to the elements that have no children: <xsl:template match="/"> <xsl:apply-templates select="//*[not(*)]"/> </xsl:template> The select pattern means: // descendants * that are elements with any name [] that have these characteristics: not() do not * have child elements Thus, the template above means "when processing the root node, don't do anything other than process the nodes in the set specified by this pattern". By "process" I mean execute the template that best matches each selected node individually. Then override the default template for element nodes by going up to the parent element instead of down to the various child nodes: <xsl:template match="*"> <!-- do something with this element --> <xsl:text>I am at element '</xsl:text> <xsl:value-of select="name(.)"/> <xsl:text>'
</xsl:text> <!-- go do something with the parent element --> <xsl:apply-templates select=".."/> </xsl:template> While this will ascend the source tree from each leaf, you don't know where you have already been, so you will return to top of the tree one time per leaf in the original set. Perhaps someone else can offer a solution for ascension without revisitation. XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: Traverse order, Charlotte.Allen | Thread | Meaning of XPath spec?, chet |
Re: Traverse order, Charlotte.Allen | Date | Re: Netscape support for XSL Styles, Chuck White |
Month |