[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] (Possible) pitfall: XSLT 2, 9.4 Creating implicit document nodes


Subject: Re: [xsl] (Possible) pitfall: XSLT 2, 9.4 Creating implicit document nodes
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Wed, 09 May 2012 11:18:08 -0400

At 2012-05-09 17:02 +0200, Christian Roth wrote:
this is a heads-up for a pitfall (that at least I have fallen into several times now...) with respect to XSLT 2, 9.4 "Creating implicit document nodes":

<http://www.w3.org/TR/xslt20/#temporary-trees>

With the source document:

--src.xml--
<a>
  <b/>
</a>
-----------

and this transformation
...
<xsl:variable name="v1"><xsl:sequence select="a"/></xsl:variable>
<xsl:variable name="v2" select="a"/>
...
However, I've spent considerable time debugging stylesheets where accessing a tunnel variable with $var/elem sometimes yielded nothing (see v2 in my example above) until I found that in some places, the variable was defined using <xsl:sequence> (because some complex content construction takes place which is either not doable or hardly readable using a single XPath expression), and using a select attribute at other places.

Fine. But the declaration you use is so very important. You've declared $v1 to be a tree and $v2 to be an element. So you've declared two very different animals and you cannot use the same syntax to address them.


$v1/a and $v2/a are both addressing the <a> child of the variable. Only $v1 has an <a> child variable. And worrisomely if the <a> in $v2 had an <a> child you would be addressing the child rather than what you want.

Is there a technique or pattern I could employ (maybe utilizing the @as attribute somehow?) to unify the access to variable contents where I know that the sequences are node sequences, regardless of their content construction using @select or <xsl:sequence>?

If you had:


  <xsl:variable name="v1" as="element()">
    <xsl:sequence select="a"/>
  </xsl:variable>
  <xsl:variable name="v2" select="a"/>

... then in both $v1 and $v2 *are* <a> (i.e. you wouldn't need to say $v/a to get at <a>). See the working example below.

Does that help? It isn't a document tree, but of course <a> can have descendants. If you want multiple elements in a sequence then use element()+.

. . . . . . . . . . . Ken

T:\ftemp>type christian.xml
<?xml version="1.0" encoding="UTF-8"?>
<a>
  <b/>
</a>

T:\ftemp>xslt2 christian.xml christian.xsl
<?xml version="1.0" encoding="UTF-8"?>v1: ab
v2: ab
T:\ftemp>type christian.xsl
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs"
  version="2.0">

  <xsl:template match="/">
    <xsl:variable name="v1" as="element()">
      <xsl:sequence select="a"/>
    </xsl:variable>
    <xsl:variable name="v2" select="a"/>


<xsl:text>v1: </xsl:text> <xsl:apply-templates select="$v1" mode="out"/> <xsl:text>&#xa;</xsl:text>

    <xsl:text>v2: </xsl:text>
    <xsl:apply-templates select="$v2" mode="out"/>
  </xsl:template>


<xsl:template match="*" mode="out"> <xsl:value-of select="name()"/> <xsl:apply-templates mode="#current"/> </xsl:template>


<xsl:template match="text()" mode="#all"/> </xsl:stylesheet> T:\ftemp>

--
Public XSLT, XSL-FO, UBL and code list classes in Europe -- Oct 2012
Contact us for world-wide XML consulting and instructor-led training
Free 5-hour lecture: http://www.CraneSoftwrights.com/links/udemy.htm
Crane Softwrights Ltd.            http://www.CraneSoftwrights.com/s/
G. Ken Holman                   mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Google+ profile: https://plus.google.com/116832879756988317389/about
Legal business disclaimers:    http://www.CraneSoftwrights.com/legal


Current Thread
Keywords