XPath

Page  1  |  2  |- 3 - 

 
   
Nodes - continued

 

An XML file, saved as a text file and named, let's say - x.xml:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="trans.xsl"?>
 
<root>
   <file>
      <sourcepath>c:\xslt\trans.xsl</sourcepath>
      <targetpath>c:\windows\temp\tmp.htm</targetpath>
   </file>
 
   <image defalt="img.jpg" ht="200">
      <!-- Hello there -->
      <!-- Hello again -->
      <name>Mat9b</name>
      <height>150</height>
      <width>150</width>
      <filesize>27.95</filesize>
      <colors>1</colors>
      <designer>myself</designer>
      <path>./project/tiles/Metal/mat9b.png</path>
   </image>
 
   <externalLink>
      <elink>
         <URLloc>ftp://test 2</URLloc>
         <Descrip>Nothing much to say</Descrip>
         <NameLabel>test 2</NameLabel>
      </elink>
      <elink>
         <URLloc>http://test1</URLloc>
         <Descrip>no link here</Descrip>
         <NameLabel>test1</NameLabel>
      </elink>
   </externalLink>
 
</root>

 

And some XSLT program, saved as a text file, and named - trans.xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
 
<xsl:template match="/">
 
   <xsl:for-each select="//self::node() | //@*">
   <!-- <xsl:for-each select="//self::node() | //@* | //namespace::*"> -->
      <xsl:value-of select="position()"/>)
       <xsl:choose>
         <xsl:when test="self::*">(ELEMENT)-</xsl:when>
         <xsl:when test="self::comment()">(COMMENT)-</xsl:when>
         <xsl:when test="self::processing-instruction()">(INSTRUCTION)-</xsl:when>
         <xsl:when test="../@*[position()]=.">(ATTRIBUTE)-</xsl:when>
         <xsl:when test="not(parent::*)">(ROOT)
            -<xsl:value-of select="descendant-or-self::node()[23]"/>-
         </xsl:when>
         <xsl:when test="self::text()">(TEXT)-</xsl:when>
         <!-- <xsl:when test="../namespace::*">(NAMESPACE)-</xsl:when> -->
      </xsl:choose>
 
      <xsl:if test="name()">(Name- <b><xsl:value-ofselect="name()"/></b>)-</xsl:if>
      <xsl:if test="self::comment()">(Comment- <xsl:value-of select="self::comment()"/>)-</xsl:if>
      <xsl:if test="@*">(Attribute- <xsl:value-of select="@*"/>)-</xsl:if>
      <xsl:if test=".">(String- <xsl:value-of select="."/>)-</xsl:if>
      <xsl:if test="current()">(Current- <xsl:value-of select="current()"/>)-</xsl:if>
      <xsl:if test="text()">(Text- <xsl:value-of select="text()"/>)-</xsl:if>
      (Id- <xsl:value-of select="generate-id()"/>)
      <br/>
   </xsl:for-each>
 
</xsl:template>
 
</xsl:stylesheet>

 

The match="/" is irrelevant, here. It's just to match the root node (actually first child) and satisfy the required form. The real node-set is all elements, comments, etc. from the XML source. It's everything. And it could be had with just a double-slash dot, abbreviation. "//self::node()" was chosen, here, because the dot might be difficult to see.

However, the attribute axis didn't get picked up. The asterick, again, looks at nodes of the type given by the axis. The asterick was an abbreviation for the node-set function - node(). Put in "//self::*", and run the program. You'll find only the ELEMENT nodes returned (not even comment nodes, or anything else). There are seven types of nodes. Node() returns more than the asterick. On eleven of the thirteen axes, a node() test looks for five of the node types - but excludes attributes and namespaces. The attribute and namespace axes must be explictly used, either with node() or the asterick.

So then, the operator - the vertical bar (union, join, etc) - was used to join with another node-set, all attribute nodes found by recursive descent. Available namespaces for each element - in-scope - were originally included, as well. But the printout, below, would have been much too long with these. So they were commented out. You can just remove the comments to test the program for yourself on an XML document that uses namespaces.

Double clicking/launching x.xml generates, in Microsoft's Internet Explorer:

1) (ROOT) -myself- (String- c:\xslt\trans.xsl c:\windows\temp\tmp.htm Mat9b 150 150 27.95 1 myself ./project/tiles/Metal/mat9b.png ftp://test 2 Nothing much to say test 2 http://test1 no link here test1 )-(Current- c:\xslt\trans.xsl c:\windows\temp\tmp.htm Mat9b 150 150 27.95 1 myself ./project/tiles/Metal/mat9b.png ftp://test 2 Nothing much to say test 2 http://test1 no link here test1 )- (Id- IDASGKFB)
2) (INSTRUCTION)-(Name- xml-stylesheet)-(String- type="text/xsl" href="trans.xsl")-(Current- type="text/xsl" href="trans.xsl")- (Id- IDAQHKFB)
3) (ELEMENT)-(Name- root)-(String- c:\xslt\trans.xsl c:\windows\temp\tmp.htm Mat9b 150 150 27.95 1 myself ./project/tiles/Metal/mat9b.png ftp://test 2 Nothing much to say test 2 http://test1 no link here test1 )-(Current- c:\xslt\trans.xsl c:\windows\temp\tmp.htm Mat9b 150 150 27.95 1 myself ./project/tiles/Metal/mat9b.png ftp://test 2 Nothing much to say test 2 http://test1 no link here test1 )- (Id- IDAEHKFB)
4) (ELEMENT)-(Name- file)-(String- c:\xslt\trans.xsl c:\windows\temp\tmp.htm )-(Current- c:\xslt\trans.xsl c:\windows\temp\tmp.htm )- (Id- IDAKHKFB)
5) (ELEMENT)-(Name- sourcepath)-(String- c:\xslt\trans.xsl)-(Current- c:\xslt\trans.xsl)-(Text- c:\xslt\trans.xsl)- (Id- IDALGKFB)
6) (TEXT)-(String- c:\xslt\trans.xsl)-(Current- c:\xslt\trans.xsl)- (Id- IDA3XKFB)
7) (ELEMENT)-(Name- targetpath)-(String- c:\windows\temp\tmp.htm)-(Current- c:\windows\temp\tmp.htm)-(Text- c:\windows\temp\tmp.htm)- (Id- IDACGKFB)
8) (TEXT)-(String- c:\windows\temp\tmp.htm)-(Current- c:\windows\temp\tmp.htm)- (Id- IDABVKFB)
9) (ELEMENT)-(Name- image)-(Attribute- img2)-(String- Mat9b 150 150 27.95 1 myself ./project/tiles/Metal/mat9b.png )-(Current- Mat9b 150 150 27.95 1 myself ./project/tiles/Metal/mat9b.png )- (Id- IDA2HKFB)
10) (ATTRIBUTE)-(Name- img)-(String- img2)-(Current- img2)- (Id- IDAIHKFB)
11) (ATTRIBUTE)-(Name- ht)-(String- 200)-(Current- 200)- (Id- IDARHKFB)
12) (COMMENT"/>-(Comment- Hello there )-(String- Hello there )-(Current- Hello there )- (Id- IDAQGKFB)
13) (COMMENT"/>-(Comment- Hello again )-(String- Hello again )-(Current- Hello again )- (Id- IDAIGKFB)
14) (ELEMENT)-(Name- name)-(String- Mat9b)-(Current- Mat9b)-(Text- Mat9b)- (Id- IDA3GKFB)
15) (TEXT)-(String- Mat9b)-(Current- Mat9b)- (Id- IDA4WKFB)
16) (ELEMENT)-(Name- height)-(String- 150)-(Current- 150)-(Text- 150)- (Id- IDAWHKFB)
17) (TEXT)-(String- 150)-(Current- 150)- (Id- IDACWKFB)
18) (ELEMENT)-(Name- width)-(String- 150)-(Current- 150)-(Text- 150)- (Id- IDAMGKFB)
19) (TEXT)-(String- 150)-(Current- 150)- (Id- IDAUWKFB)
20) (ELEMENT)-(Name- filesize)-(String- 27.95)-(Current- 27.95)-(Text- 27.95)- (Id- IDADHKFB)
21) (TEXT)-(String- 27.95)-(Current- 27.95)- (Id- IDARXKFB)
22) (ELEMENT)-(Name- colors)-(String- 1)-(Current- 1)-(Text- 1)- (Id- IDAXGKFB)
23) (TEXT)-(String- 1)-(Current- 1)- (Id- IDAGXKFB)
24) (ELEMENT)-(Name- designer)-(String- myself)-(Current- myself)-(Text- myself)- (Id- IDAOGKFB)
25) (TEXT)-(String- myself)-(Current- myself)- (Id- IDAQWKFB)
26) (ELEMENT)-(Name- path)-(String- ./project/tiles/Metal/mat9b.png)-(Current- ./project/tiles/Metal/mat9b.png)-(Text- ./project/tiles/Metal/mat9b.png)- (Id- IDAFHKFB)
27) (TEXT)-(String- ./project/tiles/Metal/mat9b.png)-(Current- ./project/tiles/Metal/mat9b.png)- (Id- IDA0WKFB)
28) (ELEMENT)-(Name- externalLink)-(String- ftp://test 2 Nothing much to say test 2 http://test1 no link here test1 )-(Current- ftp://test 2 Nothing much to say test 2 http://test1 no link here test1 )- (Id- IDAUGKFB)
29) (ELEMENT)-(Name- elink)-(String- ftp://test 2 Nothing much to say test 2 )-(Current- ftp://test 2 Nothing much to say test 2 )- (Id- IDARGKFB)
30) (ELEMENT)-(Name- URLloc)-(String- ftp://test 2)-(Current- ftp://test 2)-(Text- ftp://test 2)- (Id- IDAPHKFB)
31) (TEXT)-(String- ftp://test 2)-(Current- ftp://test 2)- (Id- IDA0VKFB)
32) (ELEMENT)-(Name- Descrip)-(String- Nothing much to say)-(Current- Nothing much to say)-(Text- Nothing much to say)- (Id- IDA5GKFB)
33) (TEXT)-(String- Nothing much to say)-(Current- Nothing much to say)- (Id- IDACXKFB)
34) (ELEMENT)-(Name- NameLabel)-(String- test 2)-(Current- test 2)-(Text- test 2)- (Id- IDAKGKFB)
35) (TEXT)-(String- test 2)-(Current- test 2)- (Id- IDADWKFB)
36) (ELEMENT)-(Name- elink)-(String- http://test1 no link here test1 )-(Current- http://test1 no link here test1 )- (Id- IDAYHKFB)
37) (ELEMENT)-(Name- URLloc)-(String- http://test1)-(Current- http://test1)-(Text- http://test1)- (Id- IDA2GKFB)
38) (TEXT)-(String- http://test1)-(Current- http://test1)- (Id- IDAEXKFB)
39) (ELEMENT)-(Name- Descrip)-(String- no link here)-(Current- no link here)-(Text- no link here)- (Id- IDA4GKFB)
40) (TEXT)-(String- no link here)-(Current- no link here)- (Id- IDAIWKFB)
41) (ELEMENT)-(Name- NameLabel)-(String- test1)-(Current- test1)-(Text- test1)- (Id- IDAAHKFB)
42) (TEXT)-(String- test1)-(Current- test1)- (Id- IDAKXKFB)

 

Of course, there is much more to XPath. This can only cover some of the basics and, hopefully, anticipate some of the potential confusion that one might encounter.


 
 More to read:

ZVON XPath by example
TopXML XPath Reference and charts
Jeni Tennison XPath (from W3C XSL WG member)
Jeni Tennison Explaining the Meunchian grouping method
Microsoft Help Microsoft's original compiled help file for msxml 4.0, with XSLT reference (click: download de SDK)
(Robin) Cover Pages Cover's XSLT/XPath links
W3C XPath version 1.0 WWW Consortium XPath spec
W3C XPath version 2.0 Much anticipated XPath 2 spec