xmlxsltxpath

XSLT - What does "/." do?


I am new to XSLT, so this question may be a bit silly. Could someone please explain to me what's going on here?

I have a simple XML document (just for testing purposes) and its stylesheet.

I don't understand why <xsl:value-of select="/."> processes all following nodes. I tested the "/." expression in XPath and it only selects the node named child.

Also, if I replace the /. with . it gives the expected result (outputs only the value of node named child).

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="style.xsl"?>
<catalog title= "Catalog">
  catalog
  <cd price = "10">
    <title> 
      title text 
      <child>child</child>
    </title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <year>1985</year>
  </cd>
  <cd price = "11">
    <title>
      second title text
      <child>second child </child>
    </title>
    <artist>Bob Dylan2</artist>
    <country>USA2</country>
    <company>Columbia2</company>
  </cd>
</catalog>

The stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" media-type="text/html"/>

  <xsl:template match="/">
    <html>
      <head>     
        <title> <xsl:value-of select="/catalog/@title" /> </title>     
      </head>
      <body> 
        <xsl:apply-templates select="/catalog/cd/title"/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="child">
    <b>
      <xsl:value-of select="/.">
      </xsl:value-of>
    </b>
    <br/>
  </xsl:template>
</xsl:stylesheet>

And the result:

title text catalog title text child Bob Dylan USA Columbia 1985 second title text second child Bob Dylan2 USA2 Columbia2
second title text catalog title text child Bob Dylan USA Columbia 1985 second title text second child Bob Dylan2 USA2 Columbia2

Solution

  • Something strange happened when you tested /. using XPath, as /. selects selects the root node, which is not an element. The root element of your XML is the one named catalog and is the only child of the root node /.

    It works rather like Unix file paths (and is designed to do so), where / is the root of the file system, as is /. because . just selects the current node relative to the previous step.

    Again, just like file paths, a relative XPath depends on the context node, so if you had used an XPath of . when your context node was child then you would have got child. But any path that starts with a slash is an absolute path and starts at the root node of the XML. A slash anywhere else is just a path separator.

    So <xsl:value-of select="/."> is the same as <xsl:value-of select="/"> and selects the string-value of the root node. In the XPath Specification it says this

    The string-value of the root node [or any element node] is the concatenation of the string-values of all text node descendants of the ... node in document order

    So you get all the text in the document.