Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using '/..' notation in XSLT XPath

Tags:

xslt

xpath

fxsl

Here is a beginner's question. What does this XPath expression /.. mean? Does it always select an empty node-set?

I've noticed that this pattern is used extensively in FXSL library, for example:

<xsl:template name="map">
  <xsl:param name="pFun" select="/.."/>
  <xsl:param name="pList1" select="/.."/>

  <xsl:for-each select="$pList1">
    <xsl:copy>
      <xsl:apply-templates select="$pFun">
        <xsl:with-param name="arg1" select="."/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:for-each>
</xsl:template>

Is it necessary to specify /.. in parameters' values here?

like image 594
Gart Avatar asked Oct 05 '11 09:10

Gart


2 Answers

The purpose of:

 <xsl:param name="pFun" select="/.."/> 

is to specify (at least in XPath 1.0 whose type system is very weak) that the type of the parameter $pFun is a node (or more generally a node-set). So, the reader knows that the value passed for this parameter shouldn't be a string or an integer.

It also specifies that the default value, if this parameter hasn't explicitly been specified on calling or applying the template, is the empty node-set.

This notation has a primarily documentation significance (but see the update at the end of this answer) and is useful only in XPath 1.0 where the type system is weak. In XPath 2.0 it is recommended to explicitly specify the type, so that the XPath processor can perform better type checking and the generated code can be more optimized and efficient.

So, in XPath 2.0 /XSLT 2.0 (in this particular case) it would be better to refactor the above to:

 <xsl:param name="pFun" as="element()"> 

There are other variations of such notation. In the early books of @Michael Kay one can also find expressions like:

@comment()

Update: the expression /.. has more practical uses than merely serving documentation purposes.

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
  <xsl:param name="pNode"/>
     <xsl:copy-of select=".|$pNode"/>
 </xsl:template>
</xsl:stylesheet>

Try to apply this transformation to any XML document. In our case, the simplest possible:

<t/>

The result is the following Saxon error message ( a similar error with other XSLT 1.0 processors):

Error at xsl:copy-of on line 8 of file:/(Untitled):
  The value is not a node-set
Transformation failed: Run-time errors were reported

Now replace:

  <xsl:param name="pNode"/>

with:

  <xsl:param name="pNode" select="/.."/>

and run the transformation again.

This time the transformation is performed without a runtime error.

Conclusion: The ability to specify an empty node-set is important in practice and the expression /.. is one way of achieving this.

like image 170
Dimitre Novatchev Avatar answered Sep 19 '22 07:09

Dimitre Novatchev


The expression /.. selects the parent of the root node, which is guaranteed to select nothing.

/ refers to the root node of the XML document, which is really an abstract concept for the top level of the document and used in XPath as the starting point to reference top-level items. It's children will always include the document element, and may also include top-level comment() and processing-instruction() that are siblings of the document element.

Is it necessary to specify /.. in parameters' values here?

No, it is not necessary to provide a default select statement for the xsl:param. It is being used in this case to explicitly define the default for those parameters to be "nothing".

like image 41
Mads Hansen Avatar answered Sep 18 '22 07:09

Mads Hansen