The XPath Node Set Functions

The XPath Node Set Functions

The following XPath functions work on node sets:

  • count( node-set ) . This function returns the number of nodes in a node set.

  • id(string ID ) . This function returns a node set of the element whose ID matches the string passed to the function, or an empty node set if no element matches.

  • last() . This function returns the number of nodes in a node set.

  • local- name ( node-set ) . This function returns the local name of the first node in the node set.

  • name( node-set ) . This function returns the qualified name of the first node in the node set.

  • namespace-uri( node-set ) . This function returns the URI of the namespace of the first node in the node set.

  • position() . This function returns the position of the context node in the context node set, starting with 1.

count()

You use the count function to count the number of nodes in a node set.

 number count(node-set) 

You pass this function a node set, and it returns the number of nodes in the node set.

You first saw the following example in Chapter 6, where I used the count function to return the number of nodes in a node set. In this case, the node set is made up of all the <PLANET> elements in planets.xml, and I get that node set using the location path //PLANET:

 <xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0">  <xsl:output method="xml" indent="yes"/>  <xsl:template match="*">      <xsl:copy>          <xsl:apply-templates/>      </xsl:copy>  </xsl:template>  <xsl:template match="PLANET">      <xsl:copy use-attribute-sets="numbering">          <xsl:apply-templates/>      </xsl:copy>  </xsl:template>  <xsl:attribute-set name="numbering">      <xsl:attribute name="number"><xsl:number/></xsl:attribute>      <xsl:attribute name="total"><xsl:value-of select="count(//PLANET)"/></xsl:attribute>  </xsl:attribute-set>  </xsl:stylesheet> 

Heres the result; note that every <PLANET> element has both a number and total attribute, and the total attribute holds the total number of <PLANET> elements, which was found with count :

 <?xml version="1.0" encoding="UTF-8"?>  <PLANETS>      <PLANET number="1" total="3">          <NAME>Mercury</NAME>          <MASS>.0553</MASS>          <DAY>58.65</DAY>          <RADIUS>1516</RADIUS>          <DENSITY>.983</DENSITY>          <DISTANCE>43.4</DISTANCE>      </PLANET>      <PLANET number="2" total="3">          <NAME>Venus</NAME>          <MASS>.815</MASS>          <DAY>116.75</DAY>          <RADIUS>3716</RADIUS>          <DENSITY>.943</DENSITY>          <DISTANCE>66.8</DISTANCE>      </PLANET>      <PLANET number="3" total="3">          <NAME>Earth</NAME>          <MASS>1</MASS>          <DAY>1</DAY>          <RADIUS>2107</RADIUS>          <DENSITY>1</DENSITY>          <DISTANCE>128.4</DISTANCE>      </PLANET>  </PLANETS> 

id()

The id function returns a node set where all the nodes have the same ID as that passed to this function. Heres how you use this function:

 node-set id(id-value) 

You pass this function an ID value and it returns the node set of nodes with that ID. Note that you can specify multiple IDs separated by whitespace, and this function returns a node set of the elements with those IDs.

The following example rule matches the text of all elements that have the ID favorite:

 <xsl:template match = "id('favorite')">      <H3><xsl:value-of select="."/></H3>  </xsl:template> 

Note also that you must declare ID values as such in a DTD or schema. A DTD for planets.xml that declares an ID named id and sets it to favorite might look like this:

 <?xml version="1.0"?>  <?xml-stylesheet type="text/xml" href="stylesheet.xsl"?>  <!DOCTYPE PLANETS [ <!ELEMENT PLANET (CUSTOMER)*>  <!ELEMENT CUSTOMER (NAME,MASS,RADIUS,DAY)>  <!ELEMENT NAME (#PCDATA)>  <!ELEMENT MASS (#PCDATA)>  <!ELEMENT RADIUS (#PCDATA)>  <!ELEMENT DAY (#PCDATA)>  <!ATTLIST PLANET      id ID #REQUIRED>  ]>  <PLANETS>      <PLANET id='favorite'>          <NAME>Mercury</NAME>          <MASS UNITS="(Earth = 1)">.0553</MASS>          <DAY UNITS="days">58.65</DAY>          <RADIUS UNITS="miles">1516</RADIUS>          <DENSITY UNITS="(Earth = 1)">.983</DENSITY>          <DISTANCE UNITS="million miles">43.4</DISTANCE><!--At perihelion-->      </PLANET>          .          .          . 

Note that some XSLT processors dont match by ID because they dont read DTDs or XML schema. This is one of the issues that XSLT 2.0 is supposed to addresshow to make ID information available.

last()

The last function returns the number of nodes in a node set, so its value is equal to the position of the last node. Heres how you use this function:

 number last() 

The following example from Chapter 5 listed the planets by name in a sentence in the result document. However, I didnt want to have the output simply say, The first three planets are: Mercury Venus Earth, but rather The first three planets are: Mercury, Venus, and Earth. I can add the correct punctuation using the position function to determine what element were working on, and use <xsl:if> to check the position, like this:

 <?xml version="1.0"?>  <xsl:stylesheet version="1.0" xmlns::xsl="http://www.w3.org/1999/XSL/Transform">  <xml:output method="xml"/>  <xsl:template match="PLANETS">  <DOCUMENT>      <TITLE>          The Planets      </TITLE>      <PLANETS>          The first three planets are: <xsl:apply-templates select="PLANET"/>      </PLANETS>  </DOCUMENT>  </xsl:template>  <xsl:template match="PLANET">      <xsl:value-of select="NAME"/>      <xsl:if test="position()!=last()">, </xsl:if>      <xsl:if test="position()=last()-1">and </xsl:if>      <xsl:if test="position()=last()">.</xsl:if>  </xsl:template>  </xsl:stylesheet> 

Heres the result:

 <?xml version="1.0" encoding="UTF-8"?>  <DOCUMENT>      <TITLE>          The Planets      </TITLE>      <PLANETS>          The first three planets are: Mercury, Venus, and Earth.      </PLANETS>  </DOCUMENT> 

local-name()

The local-name function returns the local (unqualified) name of a node. Heres how you use this function:

 string local-name(node-set?) 

You pass this function a node set with one node in it, and the function returns the local name of the node. (If the node set has more than one node, only the first is used.) If you dont pass any nodes, this function returns the local name of the context node.

In the following example, I use <xsl:element> to create new elements and local-name to find the name of context nodes, as follows :

 <?xml version="1.0"?>  <xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">      <xsl:output method="xml"/>      <xsl:template match="PLANETS">          <xsl:element name="{local-name(.)}">              <xsl:for-each select="PLANET">                  <xsl:element name="{local-name(.)}">                      <xsl:for-each select="*">                          <xsl:element name="DATA">                              <xsl:value-of select="."/>                          </xsl:element>                      </xsl:for-each>                  </xsl:element>              </xsl:for-each>          </xsl:element>      </xsl:template>  </xsl:stylesheet> 

name()

The name function is like the local-name function, except that it returns the fully qualified name of the node. Heres how you use this function:

 string name(node-set?) 

namespace-uri()

The namespace-uri function returns a string containing the URI of the namespace in a nodes expanded name. Usually, this is the URI in a namespace declaration as set with the xmlns or x mlns: prefix attributes. (See Inside XML for more details.) Heres how you use this functionnote that you can use this function only on elements or attributes; other nodes result in an empty string:

 string namespace-uri(node-set?) 

For example, I might add a namespace, star, to planets.xml:

 <?xml version="1.0"?>  <?xml-stylesheet type="text/xml" href="planets.xsl"?>  <star:PLANETS xmlns:star="http://starpowder.com">      <star:PLANET>          <star:NAME>Mercury</star:NAME>          <star:MASS UNITS="(Earth = 1)">.0553</star:MASS>          <star:DAY UNITS="days">58.65</star:DAY>          <star:RADIUS UNITS="miles">1516</star:RADIUS>          <star:DENSITY UNITS="(Earth = 1)">.983</star:DENSITY>          <star:DISTANCE UNITS="million miles">43.4</star:DISTANCE><!--At perihelion-->      </star:PLANET>      <star:PLANET>          <star:NAME>Venus</star:NAME>          <star:MASS UNITS="(Earth = 1)">.815</star:MASS>          <star:DAY UNITS="days">116.75</star:DAY>          <star:RADIUS UNITS="miles">3716</star:RADIUS>          <star:DENSITY UNITS="(Earth = 1)">.943</star:DENSITY>          <star:DISTANCE UNITS="million miles">66.8</star:DISTANCE><!--At perihelion-->      </star:PLANET>          .          .          . 

And I can find the URI of this namespace in a stylesheet with namespace-uri :

 <?xml version="1.0"?>  <xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:star="http://www.starpowder.com">  <xsl:template match="/PLANETS">      <xsl:value-of select="namespace-uri()"/>  </xsl:template>          .          .          . 

And heres the result:

 <?xml version="1.0" encoding="UTF-8"?>  http://starpowder.com 

position()

The position function returns the position of the context node:

 number position() 

Youve seen the position function throughout the book. Heres the example you saw earlier in this chapter that uses both the last and position functions to create the sentence, The first three planets are: Mercury, Venus, and Earth.:

 <?xml version="1.0"?>  <xsl:stylesheet version="1.0" xmlns::xsl="http://www.w3.org/1999/XSL/Transform">  <xml:output method="xml"/>  <xsl:template match="PLANETS">  <DOCUMENT>      <TITLE>          The Planets      </TITLE>      <PLANETS>          The first three planets are: <xsl:apply-templates select="PLANET"/>      </PLANETS>  </DOCUMENT>  </xsl:template>  <xsl:template match="PLANET">      <xsl:value-of select="NAME"/>      <xsl:if test="position()!=last()">, </xsl:if>      <xsl:if test="position()=last()-1">and </xsl:if>      <xsl:if test="position()=last()">.</xsl:if>  </xsl:template>  </xsl:stylesheet> 

And heres the result:

 <?xml version="1.0" encoding="UTF-8"?>  <DOCUMENT>      <TITLE>          The Planets      </TITLE>      <PLANETS>          The first three planets are: Mercury, Venus, and Earth.      </PLANETS>  </DOCUMENT> 


Inside XSLT
Inside Xslt
ISBN: B0031W8M4K
EAN: N/A
Year: 2005
Pages: 196

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