[xquery-talk] Xquery+ reduce two docs into one

James A. Robinson jim.robinson at stanford.edu
Fri Jan 12 20:52:10 PST 2007


 
> Actually I am very sorry, if it was not so clear what I wanted to
> achieve with my query. Maybe it was a big mistake not to post the
> whole docs.

Ah, ok. Yes, I totally misunderstood what you wanted.  As before,
David provided a very concise solution (which reproduces exactly what
you posted).  Trying to work in the new logic with my previous example,
I modified it thusly (and found myself missing XSLT key and for-each-group
functionality):

declare namespace f="uri.local-functions";

(: simulate a DB where we have a collection() function and indicies :)
declare function f:collection() {
  (doc("sebi-1.xml"), doc("sebi-2.xml"))
};

(: input meta set :)
let $metadata := f:collection()/*/meta

(: for each file referenced across all docs, build indiv :)
let $indiv  := (
  for $f in distinct-values($metadata/FileName)
  return (
    let $m := $metadata[FileName = $f]
    where (count($m) = count(f:collection()))
    return (
       <meta>{
         for $v in $m/*[not(self::FileName)]
         order by xs:integer(substring(local-name($v), 6))
         return (
           $v
         ), <FileName>{$f}</FileName>}</meta>
    )
  )
)

(: merge indiv by key constructed from Value data (I want xsl keys!) :)
let $merged := (
  for $key in distinct-values(
                for $m in $indiv
                return string-join($m/*[not(self::FileName)], ':')
  )
  return (
    let $set := $indiv[$key = string-join(./*[not(self::FileName)], ':')]
    return
      <meta>{$set[1]/*[not(self::FileName)], $set/FileName}</meta>
  )
)

(: return merged sets sorted by first FileName in merged :)
return (
  <FF>{
    for $meta in $merged
    order by xs:integer(substring(xs:string($meta/FileName[1]), 5))
    return $meta
  }</FF>
)

Produces:

<FF>
   <meta>
      <Value1>7.90mm</Value1>
      <Value2>4.0</Value2>
      <FileName>file1</FileName>
   </meta>
   <meta>
      <Value1>5.7mm</Value1>
      <Value2>4.9</Value2>
      <FileName>file2</FileName>
   </meta>
   <meta>
      <Value1>6.0mm</Value1>
      <Value2>4.9</Value2>
      <FileName>file3</FileName>
   </meta>
   <meta>
      <Value1>5.7mm</Value1>
      <Value2>2.9</Value2>
      <FileName>file4</FileName>
      <FileName>file5</FileName>
   </meta>
   <meta>
      <Value1>6.13mm</Value1>
      <Value2>5.6</Value2>
      <FileName>file6</FileName>
   </meta>
   <meta>
      <Value1>7.90mm</Value1>
      <Value2>2.8</Value2>
      <FileName>file7</FileName>
      <FileName>file8</FileName>
      <FileName>file9</FileName>
      <FileName>file14</FileName>
      <FileName>file15</FileName>
      <FileName>file16</FileName>
      <FileName>file17</FileName>
      <FileName>file18</FileName>
      <FileName>file19</FileName>
   </meta>
   <meta>
      <Value1>10.0mm</Value1>
      <Value2>4.0</Value2>
      <FileName>file10</FileName>
   </meta>
   <meta>
      <Value1>70.0mm</Value1>
      <Value2>8.0</Value2>
      <FileName>file11</FileName>
   </meta>
   <meta>
      <Value1>55.0mm</Value1>
      <Value2>6.3</Value2>
      <FileName>file12</FileName>
   </meta>
   <meta>
      <Value1>12.0mm</Value1>
      <Value2>16.0</Value2>
      <FileName>file13</FileName>
   </meta>
</FF>

Jim

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
James A. Robinson                       jim.robinson at stanford.edu
Stanford University HighWire Press      http://highwire.stanford.edu/
+1 650 7237294 (Work)                   +1 650 7259335 (Fax)


More information about the talk mailing list