Defining Relationships with Axes

 
xslt for dummies
Chapter 5 - XPath Espresso
XSLT For Dummies
by Richard Wagner
Hungry Minds 2002
  

The axis part of a location step is all about defining relationships between the current node and the nodes that you wish to select. There are 13 possible axes, which are listed in Table 5-1. Some of these axes can be abbreviated; these abbreviations are shown in the Shortened Syntax column.

Table 5-1: Axes

Axis

Relationship to Current Node

Shortened Syntax

child

Children of current node.

(no axis present denotes child axis)

self

Current node.

self::node() = .

parent

Parent of the current node. (always a single node)

parent::node() = ..

attribute

All attributes of the current node.

@

descendant

Children of current node,plus the childrens children, and so on down the tree.

 

ancestor

Parent of the current node, plus the parents parent, and so on up to and including the root node.

 

following-sibling

Siblings after the current node in the tree.

 

preceding -sibling

Siblings before the current node in the tree.

 

following

All nodes after the current node in the tree.

 

preceding

All nodes before the current node in the tree.

 

namespace

All namespace nodes of the current node.

 

descendant-or-self

Current node and all its descendant nodes.

descendant or- self:: node() = //

ancestor-or-self

Current node and all its ancestor nodes.

 

In addition to defining relationships, the axis also specifies the direction from the current node that the processor walks the tree to gather up nodes. Normally, tree walking goes top-to-bottom, left-to-right , much like you read a page in this book. However, certain axes ancestor , ancestor-or-self , preceding , and preceding-sibling travel in reverse order. (When working with attribute and namespace axes, the nodes are always unordered.)

For example, when processing a match pattern with a descendant axis, the XSLT processor starts with the first descendant defined in the source tree encountered and works its way downward until it reaches the last descendant for the current node. Or, when evaluating a preceding axis, the processor starts with the node just before the current node and works its way to the top of the document tree in reverse order. This directionality becomes important when you start thinking about the position of nodes within the node set that the axis returns. (I discuss node set positions later in this chapter.)

Child axis

Of the 13 available axes, the child axis is certainly the most common among them. It is used to select all the child nodes of the current node. The children are ordered based on the sequence in the document tree, as shown in Figure 5-3.


Figure 5-3: Nodes selected by the child axis.

For example, consider the following XML document shown in Listing 5-1, which is an XMLized version of this books table of contents.

Listing 5-1: xsltfordummies-toc.xml
start example
 <!-- xsltfordummies-toc.xml --> <book title="XSLT For Dummies"> <introduction/> <part number="I" name ="Getting Started With XSLT"> <chapter number="1"> <title>Introducing The X-Team</title> <summary>Introduce core XML/XSLT concepts</summary> </chapter> <chapter number="2"> <title>Writing Your First XSLT Stylesheet</title> <summary>Getting feet wet with a simple, practical example of transforming</summary> </chapter> </part> <part number="II" name ="Becoming An XSLT Transformer"> <chapter number="3"> <title>Transforming With Style (Stylesheets, that is)</title> <summary>Cover topics related to top level "domain": the XSL Stylesheet</summary> </chapter> <chapter number="4"> <title>Templates Rule!</title> <summary>Cover the second level domain: templates</summary> </chapter> <chapter number="5"> <title>XPath Espresso</title> <summary>Focus on the third level domain: XPath Expressions</summary> </chapter> <chapter number="6"> <title>We Want Results!</title> <summary>Provide practical examples to apply what was learned in Chapter 3-5</summary> </chapter> </part> <part number="III" name ="Prime Time XSLT"> <chapter number="7"> <title>Adding Programming Logic Isn't Just For Propheads</title> <summary>Add logic to template rules</summary> </chapter> <chapter number="8"> <title>Variables in XSLT: A Breed Apart</title> <summary>Add variables/parameters to template rules</summary> </chapter> <chapter number="9"> <title>Tweaking The Results To Get What You Want</title> <summary>Perform advanced data-related output options</summary> </chapter> <chapter number="10"> <title>To HTML And Beyond!</title> <summary>Output to HTML and other formats</summary> </chapter> <chapter number="11"> <title>Xpath Data Types and Functions</title> <summary>Cover practical examples of using built-in functions</summary> </chapter> </part> <part number="IV" name ="Extreme XSLT"> <chapter number="12"> <title>Combining XSLT Stylesheets</title> <summary>Using import and include</summary> </chapter> <chapter number="13"> <title>"Gimme Some Space" And Other Output Issues</title> <summary>Perform advanced output options</summary> </chapter> <chapter number="14"> <title>Keys and Cross-Referencing</title> <summary>Covers key and id usage</summary> </chapter> <chapter number="15"> <title>Namespaces Revisited</title> <summary>More about namespaces</summary> </chapter> <chapter number="16"> <title>Extending XSLT</title> <summary>Extensions for additional customization and power</summary> </chapter> <chapter number="17"> <title>Debugging XSLT Transformations</title> <summary></summary> </chapter> </part> <part number="V" name ="Part of Tens"> <chapter number="18"> <title> Ten Most Confusing Things About XSLT </title> </chapter> <chapter number="19"> <title>Ten All-Pro XSLT Resources On The Web</title> </chapter> <chapter number="20"> <title>Ten XSLT Processors Available Online</title> </chapter> </part> <appendix number="A" name="Glossary"/> </book> 
end example
 

Suppose you wanted to output a quick list of the book chapters. To do so, you could set up a template rule like this:

 <xsl:template match="child::chapter"> <xsl:apply-templates select="child::title"/> </xsl:template> 

Using the child axis as the starting point, the match pattern for the template looks for all chapter nodes that are children of the current node. For the returning node set, the template uses the xsl:apply-templates instruction, but does so by defining a select attribute to narrow the output to the child title elements of the returning node set. The output is:

 Introducing The X-Team Writing Your First XSLT Stylesheet Transforming With Style (Stylesheets, That Is) Templates Rule! XPath Espresso  We Want Results! Adding Programming Logic Isn't Just For Propheads Variables in XSLT: A Breed Apart Tweaking The Results To Get What You Want To HTML and Beyond! XPath Data Types and Functions Combining XSLT Stylesheets Gimme Some Space and Other Output Issues Keys and Cross-Referencing Namespaces Revisited Extending XSLT Debugging XSLT Transformations Ten Most Confusing Things About XSLT Ten All-Pro XSLT Resources On The Web Ten XSLT Processors Available Online 

 Remember   The location paths used inside the template of the template rule, such as in the select attributes of the xsl:apply-templates or xsl:value-of instructions , act off the returning node set, not the original document tree. Therefore, the current node of these select patterns is not the same as the current node of the template rules match pattern.

You may find this fact surprising, but all the examples you have seen so far in this book have used the child axis. So why have you not seen child:: before now? That is because child is the default axis for a location step, so that if you do not explicitly define an axis value, the child axis becomes the implicit axis. Therefore, if I drop child:: from the template, I get an identical result:

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

Attribute axis

The second most common axis type is attribute . The attribute axis selects all attributes of the current node. Like child:: , attribute:: has a shorter alternative, the @ symbol. Therefore, the following two are equivalent:

 <xsl:value-of select="attribute::id"/> 

and

 <xsl:value-of select="@id"/> 
start sidebar
XPath axes abbreviations

If youre like me and routinely frequent Starbucks, I suspect you too picked up the coffee lingo from the baristas. I have a favorite drink I order nearly every time I go to my local shop. I first start off by saying, Id like a grande caf mocha with half of the chocolate syrup, nonfat milk, and extra whipped cream. But over time, I learned barista-speak. Now I say, I want a grande light, nonfat, extra whipped mocha. Both are a mouthful, but the second one is quicker rolling off the tongue.

In the same way, XPath has some abbreviated ways to write axes values that make it quicker to write XPath expressions. These include:

  • child:: axis doesnt need to be explicitly defined, so you can leave it off.

  • attribute:: can be shortened to @ .

  • self::node() is abbreviated to . (single period).

  • parent::node() is shortened to .. (double period).

  • /descendant-or-self::node()/ is reduced to // .

end sidebar
 

Suppose, for example, you want to output a list of the book parts from the XML document shown in Listing 5-1. To do so, you set up a template rule like this:

 <xsl:template match="part"> Part <xsl:value-of select="@number"/>: <xsl:value-of select="@name"/> </xsl:template> 

Using the child axis as the starting point, the match pattern for the template looks for all part nodes that are children of the current node. The template uses xsl:value-of elements to output the number and name attributes of all returned part nodes as strings. The output is:

 Part I: Getting Started With XSLT Part II: Becoming An XSLT Transformer Part III: Prime Time XSLT Part IV: Extreme XSLT Part V: Part of Tens 

Parent axis

The parent axis specifies the parent of the current node (see Figure 5-4). Unlike most of the other axes, parent always refers to a single node, because a node never has two nodes as its immediate parent.


Figure 5-4: Node selected by the parent axis.

The parent axis is commonly abbreviated as .. (double periods) when it is used in combination with the node test node() . (I dont want to get ahead of myself because I talk about node tests in the next part of the chapter, but understanding this point can help you as you find out about axes.) node() is a node test that matches any node whatever kind it is. So, parent::node() means, "Dont worry about its node type; just give me the parent of the current node." (Similarly, child::node() selects all the children of the current node no matter their node type.)

To illustrate the parent axis in action, suppose you want to transform xsltfordummies-toc.xml (shown in Listing 5-1) into a result document that looks like the following:

 Chapter 1, "Introducing The X-Team", is in Part I Chapter 2, "Writing Your First XSLT Stylesheet", is in Part I Chapter 3, "Transforming With Style (Stylesheets, That Is)", is in Part II Chapter 4, "Templates Rule!", is in Part II Chapter 5, "XPath Espresso", is in Part II Chapter 6, "We Want Results!", is in Part II Chapter 7, "Adding Programming Logic Isn't Just For Propheads", is in Part III Chapter 8, "Variables in XSLT: A Breed Apart", is in Part III Chapter 9, "Tweaking The Results To Get What You Want", is in Part III Chapter 10, "To HTML and Beyond!", is in Part III Chapter 11, "XPath Data Types and Functions", is in Part III Chapter 12, "Combining XSLT Stylesheets", is in Part IV Chapter 13, "Gimme Some Space and Other Output Issues", is in Part IV Chapter 14, "Keys And Cross-Referencing", is in Part IV Chapter 15, "Namespaces Revisited", is in Part IV Chapter 16, "Extending XSLT", is in Part IV  Chapter 17, "Debugging XSLT Transformations", is in Part IV Chapter 18, "Ten Most Confusing Things About XSLT ", is in Part V Chapter 19, "Ten All-Pro XSLT Resources On The Web", is in Part V Chapter 20, "Ten XSLT Processors Available Online", is in Part V 

To get this output, you can create a template rule that looks like this:

 <xsl:template match="chapter"> Chapter <xsl:value-of select="@number"/>, "<xsl:value-of select="title"/>", is in Part <xsl:value-of select="../@number"/> </xsl:template> 

This template rule returns the chapter elements using match="chapter" . Inside the template, literal text is mixed with the following three xsl:value-of elements to get the resulting text:

  • <xsl:value-of select="@number"/> returns the number attribute for the chapter element.

  • <xsl:value-of select="title"/> returns the title child of the chapter element. (Yes, you can write it child::title .)

  • <xsl:value-of select="../@number"/> first points to the parent of the chapter element (which is always the part element) and then returns the parents number attribute with @number . The / is used to express the hierarchical relationship between the part element and its child number attribute.

Self axis

You use the self axis to select the current node, as shown in Figure 5-5.


Figure 5-5: Node selected by the self axis.

When used with the node() node test, self::node() is abbreviated as . (a single period), which in effect says, "Return the current node." For example, from Listing 5-1, to get the value of the introduction element and output it to a string, you can create a template rule like the following:

 <xsl:template match="isbn"> <xsl:value-of select="."/> </xsl:template> 

The match pattern returns the isbn element and the select="." uses the returned node itself in the xsl:value-of conversion. The end result is:

 3651-6 

Preceding-sibling and following-sibling axes

The preceding-sibling and following-sibling axes are used to select sibling nodes that come either before or after the current node (see Figures 5-6 and 5-7). Although the terms themselves are singular, preceding-sibling and following-sibling select all sibling nodes in the direction that is specified, not just the next or previous sibling.


Figure 5-6: Nodes selected by the preceding-sibling axis.

Figure 5-7: Nodes selected by the following-sibling axis.

For example, consider the following XML snippet:

 <part number="II" name ="Becoming An XSLT Transformer"> <chapter number="3"> <title>Transforming With Style (Stylesheets, that is)</title> </chapter> <chapter number="4"> <title>Templates Rule!</title> </chapter> <chapter number="5"> <title>XPath Espresso</title> </chapter> <chapter number="6"> <title>We Want Results!</title> </chapter> </part> 

Suppose your context node is the <chapter number="5"> element and you want to get the value of the title element under <chapter number="6"> . To do so, you start out by using following-sibling::chapter to get the next siblings and then a second location step that retrieves the title element children:

 <xsl:template match="chapter[@number='5']"> <xsl:value-of select="following-sibling::chapter/title"/> </xsl:template> 

See the section, Using Predicates to Get Specific, later in the chapter for a more detailed example of preceding-sibling and following-sibling .

Preceding and following axes

The preceding and following axes have a broader focus than do preceding-sibling and following-sibling . They return all the nodes, regardless of their hierarchy level, in the specified direction. preceding selects all the nodes before the current node on the tree, and following selects all the nodes after the current node. Figures 5-8 and 5-9 show these axes and their direction.


Figure 5-8: Nodes selected by the preceding axis.

Figure 5-9: Nodes selected by the following axis.

Descendant and descendant-or-self axes

The descendant axis selects all the nodes under the current node, whether they are children, grandchildren, great-grandchildren, and so on (see Figure 5-10). The descendant-or-self axis selects both the current node and all its descendants (see Figure 5-11). The descendant-or-self axis can be useful when youre uncertain of the number of levels between two nodes or if you simply want to bypass the intermediate levels.


Figure 5-10: Nodes selected by the descendant axis.

Figure 5-11: Nodes selected by the descendant-or-self axis

Ancestor and ancestor-or-self axes

The ancestor axis selects all the ancestors of the current node, and the ancestor-or-self axis selects both the current node plus all its ancestors. See Figures 5-12 and 5-13. Both axes are useful when you know a node is the current node or is above the current node in the document tree, but are not certain where.


Figure 5-12: Nodes selected by the ancestor axis.

Figure 5-13: Nodes selected by the ancestor-or-self axis.

Namespace axis

The namespace axis selects all namespaces relevant for the current node.

  
 
 
2000-2002    Feedback


XSLT For Dummies
XSLT for Dummies
ISBN: 0764536516
EAN: 2147483647
Year: 2002
Pages: 148

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net