xsl-list
[Top] [All Lists]

Re: How to write this XQuery program?

2004-09-06 13:42:24
Hi Zhimao,

Here's an implementation of Michael Kay's "second approach":
(b) sort the companies in order of price, and take the first

--- compare.xml ---
<compare>
 <p>p1</p>
 <p>p2</p>
 <c>c1.xml</c>
 <c>c2.xml</c>
 <c>c3.xml</c>
</compare>

Used as input file: you can specify any number of part id's and 
any number of 'company'-files.

The stylesheet will collect all the companies into one global variable 
with "document(/compare/c)/company", and then for each <p>,
generate a list sorted by price, outputting the first (therefore, it
needs the node-set extension).

--- compare.xsl ---
<xsl:stylesheet version="1.0" 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
 xmlns:exsl="http://exslt.org/common";
 extension-element-prefixes="exsl"


 <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

 <xsl:variable name="companies" select="document(/compare/c)/company"/>

 <xsl:template match="/compare">
  <result>
   <xsl:apply-templates select="p"/>
  </result>
 </xsl:template>

 <xsl:template match="p">
  <part>
   <id><xsl:value-of select="."/></id>
   <xsl:variable name="all">
    <xsl:for-each select="$companies/parts/part[id=current()]">
     <xsl:sort select="price" data-type="number"/>
     <price><xsl:value-of select="price"/></price>
     <company><xsl:value-of select="../../name"/></company>
    </xsl:for-each>
   </xsl:variable>
   <xsl:copy-of select="exsl:node-set($all)/price[1]"/>
   <xsl:copy-of select="exsl:node-set($all)/company[1]"/>
  </part>
 </xsl:template>

</xsl:stylesheet>

saxon output.xml compare.xml compare.xsl

--- output.xml ---
<result>
   <part>
      <id>p1</id>
      <price>100</price>
      <company>CompanyA</company>
   </part>
   <part>
      <id>p2</id>
      <price>100</price>
      <company>CompanyC</company>
   </part>
</result>

Cheers,
Anton Triest