xsl-list
[Top] [All Lists]

xsl:variable and position question and experience

2003-03-02 16:30:25


Hi,
     Extending on Jenny Tennison example of using document example to compare 
file elements
I ran into some interesting behavior regarding variables as I tried to compare 
elements in the same position in 2 files. 

Please see the examples and questions below

     Example XML Files:
     
     File Containing references to other Files
     <files>
          <file href="file1.xml" /> 
          <file href="file2.xml" /> 
     </files>
     
     file1.xml :
     <file>
     <Products>
     <Product name="1"/>
     <Product name="2"/>
     <Product name="3"/>
     </Products>
     </file>

     file2.xml :
     <file>
     <Products>
     <Product name="1"/>
     <Product name="20"/>
     <Product name="3"/>
     </Products>
     </file>

     In the stylesheet the following global variables are declared:
     <xsl:variable name="file1"
select="document(/files/file[1]/@href, /)" />
     <xsl:variable name="file2"
select="document(/files/file[2]/@href, /)" />

     Later inside template matches or for-each loops I try to use these 
variables to compare elements by position(product elements). I am unable to do 
a value-of on them.

     Example:
     1) Inside a template match on *, or $file1//Product the following 
strangeness occurs:

     <xsl:value-of select="$file1//Product[1]/@name" /> prints the name of the 
product
     but <xsl:value-of select="$file1//Product[2]/@name"/> does not print 
anything.

It seems test clauses are able to access the values in the variables but 
value-of can't.
     Example:
     2) Inside a similar template or foreach

     The following test is true when the second product in file2 is different. 
It seems the test in the match is true although the Product[1] in both files 
are the same. It is somehow matching the second products in the 2 files. Even 
so if I try to print the second product name attribute it does not work.

     <xsl:when test="$file1//Product[1]/@name != $file2//Product[1]/@name">
          CHANGE DETECTED     
          <xsl:if test="$file2//Product[1]/@name='20'">20</xsl:if>
          <!-- the test can access the second files second product-->
          <xsl:value-of select="$file2//Product[2]/@name" /> 
          <!-- the value of prints nothing proving it cannot access the second 
file's second product-->
     </xsl:when>

     
     If Product[1] is somehow iterating through the Product nodes that is cool. 
But why can't I access the value of attributes in a value-of statement when 
xsl:when or xsl:if test clauses can?
     

xsl:value of can access elements by position if the variable points to the 
specific element in the file
     Example:     
     3)     If a variable pointing to the product node is created then it is 
possible to access the Product attributes using positions. It seems positions 
only work on the element stored in the variable and not on subelements of 
elements in a variable

     The following works:
     <xsl:variable name="product1" select="document(/files/file[2]/@href, 
/)//Product" /> 
     <xsl:value-of select="$product1[2]//@name" /> 
     <!-- the second product in file can be accessed this way-->

     but I don't understand why. It is in convenient to have to create many 
variables for a file to access each element that needs to be accessed by 
position.


     If you can explain why these things work the way they do please let me 
know or if are these idiosyncrasies are bugs?

     Also I have tried this in xalan and saxon and get the same behavior, so I 
assume this is not a bug but a lack of understanding on my part.

thanks

DS





_______________________________________________
Join Excite! - http://www.excite.com
The most personalized portal on the Web!

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



<Prev in Thread] Current Thread [Next in Thread>