[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Why do these xsl:variable declarations give differ

Subject: Re: Why do these xsl:variable declarations give different results?
From: Michael Kay <mike@xxxxxxxxxxxx>
Date: Thu, 20 Dec 2012 23:42:00 +0000
Re:  Why do these xsl:variable declarations give differ
Are we talking XSLT 1.0 or 2.0 here?

The first variable is a set (2.0: sequence) of nodes, being ancestor nodes of the context node. Because of the predicate [position()=last()] this node set/sequence will contain at most one node. The value of $containingChapter/@id is therefore a set (2.0: sequence) of attribute nodes, again containing at most one node. The value is NOT a string, but it can for most purposes be treated as if it were. (An exception would be that boolean() applied to the value behaves differently).

The second variable is a document node (2.0: result tree fragment) containing copies of the ancestor nodes of the context node. As it is a document node and document nodes do not have attributes, $containingChapter/@id will inevitably select nothing (in XSLT 1.0, it's an error, because you can't have a result-tree-fragment on the lhs of the "/" operator).

This difference between variables defined using @select and variables defined using contained instructions is very fundamental and important to understand.

Michael Kay
Saxonica


On 20/12/2012 23:24, Steve Fogel wrote:
Hi, all.

Would appreciate some help. I don't understand how these two definitions of a variable produce different results. This is from the DITA Open Toolkit (OT).
1st alternate definition is without a condition:


<xsl:variable name="containingChapter"
      select="ancestor-or-self::*[contains(@class, ' topic/topic ')][position()=last()]"/>

2nd alternate definition is with a condition, which is me fixing a bug in the (OT).

<xsl:variable name="containingChapter">
     <xsl:choose>
         <xsl:when test="$hasBookParts">  <!-- The book has <part>s -->
             <xsl:copy-of select="ancestor-or-self::*[contains(@class, ' topic/topic ')][last()-1]"/>
         </xsl:when>
         <xsl:otherwise>
             <xsl:copy-of select="ancestor-or-self::*[contains(@class, ' topic/topic ')][last()]"/>
         </xsl:otherwise>
     </xsl:choose>
</xsl:variable>


Both definitions should return a <topic> element with an id attribute. Following the definition is this statement:


<xsl:variable name="id" select="$containingChapter/@id"/>

With the first definition, the value of id is a string, as desired. With the 2nd, it's empty. Bad. Why?

For the 1st definition, the Oxygen debugger gives the value type as "element(1)". For the 2nd, it gives the value type as "document-node(1)". In fact, if you look at the value of the variable in Oxygen's Nodes/Values Set window, for the 1st definition it is:

topic

and for the 2nd, it is:

#document/fragment
    topic

Can someone please advise?

Many thanks!

Steve

Steve Fogel | Information Architect, Oracle Database | 650.506.4914
Oracle Server Technologies Information Development
500 Oracle Parkway | M/S 4op1126 | Redwood Shores, CA 94065

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.