Sunday, 17 July 2011

Node Set Functions

XPath Node Set

A node set is a set of nodes. When you write an XPath expression to return one or more nodes, you call these nodes a node set.

For example, if you use the following expression to return a node called "title", you will have a set of nodes all called "title" (assuming there's more than one record).

 child::title 
Node Set Functions

You can use the following functions when working with node sets:

FunctionDescription
last()Returns the number of nodes in a node set.
position()Returns the position of the context node (current node). The starting value is 1. As you loop through each node, the position increments.
count(node1, node2, ...)Returns the total number of nodes in the node set as provided between the parentheses. If you leave the parentheses blank, it will use the context node.
id((string1, string2, ...) node)Returns the nodes whose ID matches the string/s passed to the function.
local-name(node_set)Returns the local name of the first node in the node set. The local name is the name without the namespace prefix. To use the context node, simply leave node_set blank.
namespace-uri(node_set)Returns the URI of the namespace of the first node in the node set. To use the context node, leave node_set blank.
name(node_set)Returns the full, qualified name of the first node in the node set. To use the context node, simply leave node_set blank.
Node Set Function Example

The Source XML File

Imagine we have the following XML file:

 <?xml version="1.0"?> <food_list>   <food_item type="vegetable">     <name>Agar</name>     <carbs_per_serving>81</carbs_per_serving>     <fiber_per_serving>8</fiber_per_serving>     <fat_per_serving>0.5</fat_per_serving>     <kj_per_serving>1280</kj_per_serving>   </food_item>   <food_item type="vegetable">     <name>Asparagus</name>     <carbs_per_serving>1</carbs_per_serving>     <fiber_per_serving>1</fiber_per_serving>     <fat_per_serving>0</fat_per_serving>     <kj_per_serving>40</kj_per_serving>   </food_item>   <food_item type="vegetable">     <name>Cabbage</name>     <carbs_per_serving>0</carbs_per_serving>     <fiber_per_serving>1</fiber_per_serving>     <fat_per_serving>0</fat_per_serving>     <kj_per_serving>14</kj_per_serving>   </food_item>   <food_item type="vegetable">     <name>Potato</name>     <carbs_per_serving>21.5</carbs_per_serving>     <fiber_per_serving>2</fiber_per_serving>     <fat_per_serving>1</fat_per_serving>     <kj_per_serving>460</kj_per_serving>   </food_item>   <food_item type="vegetable">     <name>Pumpkin</name>     <carbs_per_serving>6</carbs_per_serving>     <fiber_per_serving>1</fiber_per_serving>     <fat_per_serving>0.5</fat_per_serving>     <kj_per_serving>150</kj_per_serving>   </food_item>   <food_item type="vegetable">     <name>Yam</name>     <carbs_per_serving>30.5</carbs_per_serving>     <fiber_per_serving>2</fiber_per_serving>     <fat_per_serving>0.5</fat_per_serving>     <kj_per_serving>550</kj_per_serving>   </food_item>   <food_item type="vegetable">     <name>Zucchini</name>     <carbs_per_serving>1.5</carbs_per_serving>     <fiber_per_serving>1.5</fiber_per_serving>     <fat_per_serving>0.5</fat_per_serving>     <kj_per_serving>55</kj_per_serving>   </food_item>   <food_item type="seafood">     <name>Abalone</name>     <carbs_per_serving>0</carbs_per_serving>     <fiber_per_serving>0</fiber_per_serving>     <fat_per_serving>1</fat_per_serving>     <kj_per_serving>400</kj_per_serving>   </food_item>   <food_item type="seafood">     <name>Barramundi</name>     <carbs_per_serving>0</carbs_per_serving>     <fiber_per_serving>0</fiber_per_serving>     <fat_per_serving>2</fat_per_serving>     <kj_per_serving>390</kj_per_serving>   </food_item>   <food_item type="fruit">     <name>Apple</name>     <carbs_per_serving>15</carbs_per_serving>     <fiber_per_serving>2.5</fiber_per_serving>     <fat_per_serving>0</fat_per_serving>     <kj_per_serving>250</kj_per_serving>   </food_item>   <food_item type="fruit">     <name>Kiwi Fruit</name>     <carbs_per_serving>7.5</carbs_per_serving>     <fiber_per_serving>2.5</fiber_per_serving>     <fat_per_serving>0</fat_per_serving>     <kj_per_serving>150</kj_per_serving>   </food_item>   <food_item type="grain">     <name>Oatbran</name>     <carbs_per_serving>62</carbs_per_serving>     <fiber_per_serving>14</fiber_per_serving>     <fat_per_serving>7</fat_per_serving>     <kj_per_serving>1400</kj_per_serving>   </food_item>   <food_item type="grain">     <name>Wheatgerm</name>     <carbs_per_serving>1.5</carbs_per_serving>     <fiber_per_serving>1</fiber_per_serving>     <fat_per_serving>0.5</fat_per_serving>     <kj_per_serving>70</kj_per_serving>   </food_item> </food_list> 

The Requirement

Now, imagine we want to display the contents of the file in a table, and that we want to have a "counter" column that provides the count of each row. Something like this:

XPath node set example

The Solution

We could achieve the above requirement using the XPath position() function, as follows:

 <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  <xsl:template match="/">   <xsl:apply-templates/> </xsl:template>  <xsl:template match="food_list">   <table border="1"  style="background-color:#cccc00">     <tr>       <th>Node Position</th>       <th>Food Item</th>       <th>Carbs (g)</th>       <th>Fiber (g)</th>       <th>Fat (g)</th>       <th>Energy (kj)</th>     </tr>     <xsl:for-each select="food_item">       <tr>         <td><b><xsl:value-of select="position()"/></b></td>         <td><xsl:value-of select="name"/></td>         <td><xsl:value-of select="carbs_per_serving"/></td>         <td><xsl:value-of select="fiber_per_serving"/></td>         <td><xsl:value-of select="fat_per_serving"/></td>         <td><xsl:value-of select="kj_per_serving"/></td>       </tr>     </xsl:for-each>   </table> </xsl:template>  </xsl:stylesheet> 

No comments:

Post a Comment