xsl-list
[Top] [All Lists]

RE: sorting on data referenced with document()??

2002-09-17 18:27:51
hmm...

I figured that I would first try the extension function route, but I can't 
quite figure out how to get it working.  Excuse my ignorance, I am a xslt 
beginner and I have never added a.

anyway, I tried to first download the function itself:
http://www.exslt.org/exsl/functions/node-set/exsl.node-set.zip

but inside the zip, exsl.node-set.xsl isn't present.????

the only way I could get exsl.node-set.xsl in any manner is to download the all 
modules zip. 
http://www.exslt.org/all-exslt.zip
exsl.node-set.1.xsl and exsl.node-set.2.xsl are in that zip, so I am guessing 
that those are what I need.
I put these 2 xsl files in the same folder as my two.xsl

so I try to modify my stylesheet:
------------------------------------------------------
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; 
xmlns:common="http://exslt.org/common"; xmlns="http://www.w3.org/tr/REC-html40"; 
version="1.0">
<xsl:import href="exsl.node-set.1.xsl" />
<xsl:import href="exsl.node-set.2.xsl" />
------------------------------------------------------

I add the variable as instructed (i hope this is right):
------------------------------------------------------
<xsl:variable name="persons">
   <xsl:for-each select="people/person">
     <xsl:copy>
       <xsl:copy-of select="@*"/>
       <xsl:copy-of select="*"/>
       <xsl:variable name="ownerName" select="@name"/>
       <xsl:for-each select="document('xml2.xml')">
         <xsl:copy-of select="key('turtleByOwner', $ownerName)"/>
       </xsl:for-each>
     </xsl:copy>
   </xsl:for-each>
</xsl:variable>
------------------------------------------------------

and I change the for each in the stylesheet to:
------------------------------------------------------
<xsl:for-each select="exsl:node-set($persons)/person">
------------------------------------------------------

I try to transform with xalan at my command line and I get:
------------------------------------------------------
java org.apache.xalan.xslt.Process -in xml1.xml -xsl two.xsl -out 2.html
file:///C:/xsl/two.xsl; Line 25; Column 57; XSLT Error (javax.xml.transform.Tran
sformerConfigurationException): javax.xml.transform.TransformerException: javax.
xml.transform.TransformerException: Prefix must resolve to a namespace: exslt
------------------------------------------------------

what am I doing wrong?
will

-----Original Message-----
From: Joerg Heinicke [mailto:joerg(_dot_)heinicke(_at_)gmx(_dot_)de]
Sent: Monday, September 16, 2002 7:40 PM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] sorting on data referenced with document()??


Hello Will,

you either have to statically change the context to the second document

<xsl:for-each select="document('xml2.xml')/people/person">
   <xsl:sort select="turtle"/>
   ...
</xsl:for-each>

(but I think that's not an option)

or you have to create a temporary tree with all information merged. You 
can do this either via a 2 transformations or using an extension 
function exslt:node-set(). While extension functions always have the 
disadvantage of less portability, exslt is an approach against that 
matter (http://www.exslt.org).

<xsl:variable name="persons">
   <xsl:for-each select="people/person">
     <xsl:copy>
       <xsl:copy-of select="@*"/>
       <xsl:copy-of select="*"/>
       <xsl:variable name="ownerName" select="@name"/>
       <xsl:for-each select="document('xml2.xml')">
         <xsl:copy-of select="key('turtleByOwner', $ownerName)"
       </xsl:for-each>
       <xsl:copy-of select="
     </xsl:copy>
   </xsl:for-each>
</xsl:variable>

<xsl:for-each select="exslt:node-set($persons)/person">
   <xsl:sort select="cat"/> <!-- or turtle -->
   ...
</xsl:for-each>

Other comments to your stylesheet:

Are you sure you want version="2.0"??
In the match attribute of the key, you don't need //. The key indexes 
the whole XML tree (so all turtle elements, even without //).

Regards,

Joerg

Carter, Will wrote:
Hi,

I have a sorting problem when I use xsl to combine data from 2 xml files into 
one html output.

here is my xml file 1 (xml1.xml):
-----------------------
<people>
      <person name="george">
              <cat>cat-zoro</cat>
              <dog>dog-butch</dog>
              <fish>fish-jaws</fish>
      </person>
      <person name="jennifer">
              <cat>cat-felix</cat>
              <dog>dog-fido</dog>
              <fish>fish-moby</fish>
      </person>
      <person name="simon">
              <cat>cat-tom</cat>
              <dog>dog-scooby</dog>
              <fish>fish-conroy</fish>
      </person>
</people>
-----------------------

here is my xml file 2 (xml2.xml):
-----------------------
<people>
      <person name="george">
              <turtle>turtle-greeny</turtle>
      </person>
      <person name="jennifer">
              <turtle>turtle-browny</turtle>
      </person>
      <person name="simon">
              <turtle>turtle-red</turtle>
      </person>
</people>
-----------------------

here is my stylesheet:
-----------------------
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; 
xmlns="http://www.w3.org/tr/REC-html40"; version="2.0">
<xsl:key name="turtleByOwner" match="//turtle" use="../@name" />
<xsl:template match="/">
<table border="1" cellspacing="0" cellpadding="0">
      <xsl:for-each select="people/person">
      <xsl:sort select="cat"/>
      <tr>
              <td colspan="7">Person: <xsl:value-of select="@name"/></td>
      </tr>
      <tr>
              <td><xsl:value-of select="cat"/></td>
              <td><xsl:value-of select="dog"/></td>
              <td><xsl:value-of select="fish"/></td>
              <xsl:variable name="ownerName" select="@name"/>
              <td>
              <xsl:for-each select="document('xml2.xml')">
              <xsl:value-of select="key('turtleByOwner', $ownerName)"
              </xsl:for-each>
              </td>
      </tr>
      </xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
-----------------------

this correctly produces (sorted by cat):
-----------------------
Person: jennifer 
cat-felix   dog-fido   fish-moby   turtle-browny 
  
Person: simon 
cat-tom   dog-scooby   fish-conroy   turtle-red 
  
Person: george 
cat-zoro   dog-butch   fish-jaws   turtle-greeny 
-----------------------


but I want to sort by turtle (I want this output):
-----------------------
Person: jennifer 
cat-felix   dog-fido   fish-moby   turtle-browny 

Person: george 
cat-zoro   dog-butch   fish-jaws   turtle-greeny 
 
Person: simon 
cat-tom   dog-scooby   fish-conroy   turtle-red 
-----------------------

I changed the sort line to be:
<xsl:sort select="turtle"/>
but it doesn't work, my output is:
-----------------------
Person: george 
cat-zoro   dog-butch   fish-jaws   turtle-greeny 
  
Person: jennifer 
cat-felix   dog-fido   fish-moby   turtle-browny 
  
Person: simon 
cat-tom   dog-scooby   fish-conroy   turtle-red 
-----------------------

how can I sort on the turtle column from the document reference?

thanks for any ideas.
will


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


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