XqueryGen – XQuery-Sematik-Definition (25.08.2004)




Nr Sreenshot Interpretation XQuery Beispiel XML Data Beispiel


Allgemein gilt:
Jedes Ergebnis wird mit einen <result/> tag umschlossen.


1 - Liste mit allen <proj> Elementen.
- Keine Eltern-Elemente

<result>
{
for $i in doc("statisticsDB.xml")/
statisticsDB/cityStatistics/organization/funding/*
where local-name( $i ) = 'proj'
return
$i
}
</result>
---------------------------------------------------------
<result>
{
for $i in doc("statisticsDB.xml")/
statisticsDB/cityStatistics/
organization/funding/proj
return
$i
}
</result>
---------------------------------------------------------
ohne include Tag
---------------------------------------------------------
<result>
{
for $i in doc("statisticsDB.xml")/
statisticsDB/cityStatistics/
organization/funding/*[local-name() = 'proj']
return
data($i)
}
</result>

<result>
 <proj>HumMer</proj>
  <proj>ABC</proj>
  <proj>XYZ</proj>
</result>



---------------
ohne
"includeTag"
<result>
  HumMer
  ABC
  XYZ UVW
</result>
2 - Liste mit Element-Tripeln
- Aufgabe der einzelnen Assoziationen: Kein Trennelement
- Auch wenn ein Element fehlt, wird der Rest des Tripels ausgegeben.

<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/
cityStatistics/organization/funding/*
where local-name( $i ) = 'proj' or local-name( $i ) = 'faid'
or local-name( $i ) = 'recv'
return
$i
}
</result>
----------------------------------------------
<result>
{
for $i in document("statisticsDB.xml")/statisticsDB/cityStatistics/
organization/funding/
*[ local-name() = 'proj'
or
local-name() = 'faid'
or
local-name() = 'recv' ]
return
$i
}
</result>

----------------------------------------------
Problem: Dublikate
----------------------------------------------
<result>
{for $i in document("statisticsDB.xml")/
statisticsDB/cityStatistics/organization/funding/proj
union
document("statisticsDB.xml")/
statisticsDB/cityStatistics/organization/funding/recv
return
$i
}
</result>

----------------------------------------------
Problem: Document Order
----------------------------------------------
<result>
{
for $i in document("statisticsDB.xml")/
statisticsDB/cityStatistics/organization/funding
return
(
$i/proj,
$i/recv
)
}
</result>
<result>
  <proj>ABC</proj>
  <faid>13312</faid>
  <recv>yes</recv>
  <proj>XYZ</proj>
  <proj>ABC</proj>
  <faid>13312</faid>
  <proj>ABC</proj>
  <faid>13312</faid>
  <recv>yes</recv>
</result>

3
- Liste mit <funding> Elementen
- Subelemente werden ignoriert.

- Interessant wäre es dann hier z.B. Aggregation anzuwenden.
Vielleicht sogar implizit!?
NEIN!


<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/organization/*
where local-name( $i ) = 'funding'
return
element {node-name($i)} {}
}
</result>

----------------------------------------------------------
<result>
{
   for $i in doc("statisticsDB.xml")/
statisticsDB/cityStatistics/organization/funding
   return
      element {node-name($i)} {}
}
</result>
----------------------------------------------------------
<result>
{
for $i in doc("statisticsDB.xml")/
statisticsDB/cityStatistics/organization/funding
return
<funding/>
}
</result>

----------------------------------------------------------


<result>
 <funding/>
 <funding/>
 <funding/>
</result>
4

<Funding> hat MIXED CONTENT!!!
- kein Unterschied zu dem Fall darüber, da der text()-Knoten nicht markiert ist


     s.o.
<result>
 <funding/>
 <funding/>
 <funding/>
</result>
5

<Funding> hat MIXED CONTENT!!!
zustätzlich ist der "text()" Knoten unter funding markiert !!!
- Liste mit Funding Elementen
(je nach Aktivität der show-Tag-Checkbox) und dem jeweiligen text() Anteil.
- Semantik je nach dem was XQuery dann eigentlich macht.

<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/organization/*
where local-name( $i ) = 'funding'
return
element {node-name($i)} { $i/text() }
}
</result>

----------------------------------------------------------
normalized-space ?!?
----------------------------------------------------------


<result>
  <funding>
    der mixed Anteil
  </funding>
  <funding>
    der mixed Anteil
    und mehr
  </funding>
</result>
6

- Liste mit <funding> Elementen und jeweils  den Subelementen.
- Wenn ein Subelement fehlt, wird es halt ignoriert.
- Assoziationen zwischen <proj> und <faid> beleiben erhalten
(denn sie sind in einem jeweils eigenen <funding> Element.

- Dies ist der klassische Fall einer Anfrage.

<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/organization/*
where local-name( $i ) = 'funding'
return
element {node-name($i)} {
for $j in $i/*
where local-name( $j ) = 'proj' or local-name( $j ) = 'faid'
return
$j (: nur Variable, das simple type :)
}
}
</result>

---------------------------------------------------------
<result>
{
for $i in doc("statisticsDB.xml")/
statisticsDB/cityStatistics/organization/funding
return
element {node-name($i)} { $i/*[local-name() = 'proj'
or
local-name() = 'faid'] }
}
</result>


<result>
  <funding>
    <proj>ABC</proj>
    <faid>13312</faid>
   </funding>
  <funding>
    <proj>XYZ</proj>
    <faid>1asd2</faid>
  </funding>
  <funding>
    <faid>1asas</faid>
  </funding>
  <funding>
    <proj>dfhr</proj>
  </funding>
</result>
7
- ungültig

- eventuell misbrauchen in der GUI: Wenn ein solcher Knoten markiert wird,
werden automatisch alle direkten Kinder markiert.

n.a.
n.a.
8
- ungültig

- d.h. die all-Markierung wird ignoriert bzw. es ist gar nicht erst markierbar

<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/
organization/funding/*
where local-name( $i ) = 'proj' or local-name( $i ) = 'faid'
return
$i
}
</result>



<result>
  <proj>ABC</proj>
  <recv>yes</recv>
  <proj>XYZ</proj>
  <proj>ABC</proj>
  <proj>ABC</proj>
  <recv>yes</recv>
</result>
9
- eine liste von "financial"-tags mit dazugehörigen
attribut-werte-paaren von "myattribute"

- in diesem Fall ist die tag-checkbox inaktiv - d.h. es ist nicht möglic sie zu betätigen
----------------- ist mehr im schema F - siehe nächsten Fall
<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name( $i ) = 'financial'
return
if ( exists( $i/@myattribute ) ) then
element {node-name($i)} { $i/@myattribute }
else
()
}
</result>

----------------- ist schöner
<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name( $i ) = 'financial' and $i/@myattribute
return
element {node-name($i)} { $i/@myattribute }
}
</result>

------------------------------------------------------
<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/
financial[@myattribute]
return
element {node-name($i)} { $i/@myattribute }
}
</result>



<result>
   <financial myattribute=  "attributwert1"/>
   <financial myattribute=  "attributwert2"/>
   <financial myattribute=  "attributwert3"/>
   <financial myattribute=  "attributwert4"/>
</result>
10
a
 14.jpg
- Liste von
(1) "financial"-tags mit dazugehörigen "myattribute"-Attributen
oder (2) "amount"-tags mit inhalt
<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name( $i ) = 'financial'
return
(
if ( exists( $i/@myattribute ) ) then
element {node-name($i)} { $i/@myattribute }
else
(),
for $j in $i/*
where local-name( $j ) = 'amount'
return
$j
)
}
</result>
--------------------------------------------------------
<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/financial
return
(
if ( exists( $i/@myattribute ) ) then
element {node-name($i)} { $i/@myattribute }
else
(),
for $j in $i/amount
return
$j
)
}
</result>




<result>
   <financial myattribute=  "attributwert1"/>
   <amount>
        blanasdd
   </amount>
   <financial myattribute=  "attributwert2"/>
   <financial myattribute=  "attributwert3"/>
   <financial myattribute=  "attributwert4"/>
</result>
10
b
23
- Liste von "financial"-tags mit dazugehörigen "myattribute"-Attributen
(falls vorhanden) und dessen "amount"-tags mit inhalt


<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name($i) = 'financial'
return
element { node-name($i) }
{
$i/@myattribute,
for $k in $i/*
where local-name($k) = 'amount'
return
$k
}
}
</result>


<result>
  <financial myattribute="christoph">
    <amount>12350</amount>
  </financial>
  <financial myattribute="christoph">
    <amount>12350</amount>
  </financial>
  <financial myattribute="christoph">
    <amount>12350</amount>
  </financial>
  <financial myattribute="robert">
    <amount>500</amount>
  </financial>
  <financial>
    <amount>3500</amount>
  </financial>
  <financial>
    <amount>25000</amount>
  </financial>
  <financial>
    <amount>5000</amount>
  </financial>
  <financial>
    <amount>10000</amount>
  </financial>
</result>
11
- Liste von "Orgainsation"  und "Financial"
- wenn ein Element fehlt, dann fehlt es halt
- Assoziationen zwischen Orgainsationen und Financials gehen verloren.

<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name( $i ) = 'organization' or local-name( $i ) = 'financial'
return
element {local-name($i)} {}
}
</result>
-------------------------------
<result>
{
for $i in doc("statisticsDB.xml")/
statisticsDB/cityStatistics/
*[ local-name() = 'organization'
or
local-name() = 'financial' ]
return
element {node-name($i)} {}
}
</result>


<result>
 <organisation/>
  <financial/>
  <financial/>
  <organisation/>
  <financial/>
  <organisation/>
  <financial/>
</result>
12
- Liste von "statisticsDB" (einelementig, da das root-Element)
die Liste von "cityStatistics" die Liste von "organisation"
die Liste von "cid" / "cname" enthält

<result>
{
for $l in doc("statisticsDB.xml")/*
where local-name($l) = 'statisticsDB'
return
element {node-name($l)}
{
for $i in $l/*
where local-name($i) = 'cityStatistics'
return
element {node-name($i)}
{
for $j in $i/*
where local-name($j) = 'organization'
return
element {node-name($j)}
{
for $k in $j/*
where local-name($k) = 'cid' or local-name($k) = 'cname'
return
$k
}
}
}
}
</result>
-----------------------------------------------------------

<result>
{
for $l in doc("statisticsDB.xml")/*[local-name() = 'statisticsDB']
return
element {node-name($l)}
{
for $i in $l/*[local-name() = 'cityStatistics']
return
element {node-name($i)}
{
for $j in $i/*[local-name() = 'organization']
return
element {node-name($j)}
{
for $k in $j/*[ local-name() = 'cid' or local-name() = 'cname']
return
element {node-name($k)} { data( $k ) }
}
}
}
}
</result>


<result>
   <statisticsDB>
       <cityStatistics>
          <organisation>
              <cid>wert1</cid>
               <cname>wert2</cname>
           </organisation>
          <organisation>
              <cid>wertA</cid>
               <cname>wertB</cname>
           </organisation>
       </cityStatistics>
       <cityStatistics>
          <organisation>
              <cid>wertX</cid>
           </organisation>
          <organisation>
               <cname>wertY</cname>
           </organisation>
       </cityStatistics>
  </statisticsDB>
</result>
13
15.jpg

<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name($i) = 'organization' or local-name($i) = 'financial'
return
(
if ( local-name($i) = 'organization' ) then
element {node-name($i)}
{
for $j in $i/*
where local-name($j) = 'funding'
return
element {node-name($j)}
{
for $k in $j/*
where local-name($k) = 'gid'
return
$k
}
}
else
(),
if ( local-name($i) = 'financial' ) then
element {node-name($i)}
{
for $l in $i/*
where local-name($l) = 'aid'
return
$l
}
else
()
)
}
</result>


---------------------------------------------------------------
problem: falls organization auch aid-kinder hat
---------------------------------------------------------------
<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
      where local-name($i) = 'organization' or local-name($i) = 'financial'
      return
         element {node-name($i)}
            {
        (
            for $j in $i/*
            where local-name($j) = 'funding'
            return
               element {node-name($j)}
                  {
                  for $k in $j/*
                  where local-name($k) = 'gid'
                     return
                        $k
                   }
            ,
            for $l in $i/*
            where local-name($l) = 'aid'
            return
               $l
        )
            }
}
</result>



14
16.jpg

<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name($i) = 'organization' or local-name($i) = 'financial'
return (
if ( local-name( $i ) = 'organization' ) then
for $j in $i/*
where local-name($j) = 'funding'
return
element {node-name($j)}
{
for $k in $j/*
where local-name($k) = 'gid'
return
$k
}
else (),
if (local-name( $i ) = 'financial' ) then
element {node-name($i)} {
for $j in $i/*
where local-name($j) = 'aid'
return
$j
}
else ()
)
}
</result>





15
Hier ein Bsp., in dem funding, proj und cid markiert sind
- Liste von "cid" / "funding" Elementen,
wobei in den "funding"  Elementen wiederum eine Liste von "proj" Elementen ist

<result>
{
for $l in doc("statisticsDB.xml")/statisticsDB/cityStatistics/organization/*
where local-name( $l ) = 'cid' or local-name( $l ) = 'funding'
return
(
if (local-name($l) = 'cid') then
$l
else (),
if (local-name($l) = 'funding') then
element {node-name($l)}
{
for $i in $l/*
where local-name( $i ) = 'proj'
return
$i
}
else ()
)
}
</result>

<result>
  <cid>
    cidWert1
  </cid>
  <funding>
    <proj>
      projWert1
    </proj>
  </funding>
  <funding>
    <proj>
      projWert2
    </proj>
  </funding>
  <funding>
    <proj>
      projWert3
    </proj>
  </funding>
  <cid>
    cidWert2
  </cid>
</result>
16
- Liste von "Orgainsation"  und "Financial"
- wenn ein Element fehlt, dann fehlt es halt
- Assoziationen zwischen Orgainsationen und Financials bleiben NICHT  erhalten,
da umschließendes "cityStatistics" nicht mit ausgewählt ist
- es gibt lediglich die Assoziation der "statisticsDB", die recht groß ist


<result>
{
for $i in doc("statisticsDB.xml")/*
      where local-name($i) = 'statisticsDB'
      return
         element {node-name($i)}
     {
            for $j in $i/*
            where local-name($j) = 'cityStatistics'
            return
               for $k in $j/*
               where local-name($k) = 'organization' or local-name($k) = 'financial'
                  return
             (
             if ( local-name($k) = 'organization') then
                        element { node-name($k) }  {}
             else (),
             if ( local-name($k) = 'financial') then
                        element { node-name($k) }  {}
             else ()
             )
         }
}     
</result>
-----------------------------------------
ist das nicht richtiger (eine for-schleife weniger) ... in abstimmung mit melanie ...
-----------------------------------------

<result>
{
for $i in doc("statisticsDB.xml")/*
      where local-name($i) = 'statisticsDB'
      return
         element {node-name($i)}
         {
            for $k in $i/cityStatistics/*
            where local-name($k) = 'organization' or local-name($k) = 'financial'
               return
                  (
                  if ( local-name($k) = 'organization') then
                     element { node-name($k) }  {}
                  else (),
                  if ( local-name($k) = 'financial') then
                     element { node-name($k) }  {}
                  else ()
                  )
         }
}    
</result>


<result>
  <statisticsDB>
      <organisation/>
      <financial/>
      <organisation/>
      <financial/>
      <organisation/>
      <financial/>
      <organisation/>
      <financial/>
  </statisticsDB>
 
falls es mehrere "statisticsDBs" geben würde:
 <statisticsDB>
      <organisation/>
      <financial/>
  </statisticsDB>
  <statisticsDB>
      <organisation/>
  </statisticsDB>
  <statisticsDB>
      <financial/>
  </statisticsDB>
</result>
17 17


<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name($i) = 'organization' or local-name($i) = 'financial'
return (
if ( local-name( $i ) = 'organization' ) then
for $k in $i/*
where local-name($k) = 'cid'
return
$k
else (),
if (local-name( $i ) = 'financial' ) then
for $k in $i/*
where local-name($k) = 'aid'
return
$k
else ()
)
}
</result>

<result>
  <cid>MSFT</cid>
  <aid>Sk31(SQLServer12350G006MicrosoftRedmondMSFT)</aid>
  <aid>MSFT</aid>
  <aid>HP</aid>
  <aid>Sk31(Leo500G005MicrosoftRedmondMSFT)</aid>
  <cid>IBM</cid>
  <cid>NA</cid>
  <aid>Sk31(Clio3500G004International Business MachinesSan JoseIBM)</aid>
  <aid>Sk31(DB225000G001International Business MachinesSan JoseIBM)</aid>
  <aid>Sk31(FastNetwork5000G007Network AssociatesSan JoseNA)</aid>
  <aid>Sk31(Clio10000G003International Business MachinesSan JoseIBM)</aid>
</result>


Allgemeines zu join-Attributen:

Die Selektion eines Joins gilt immer auf der Ebene auf der er definiert wird.
D.h. will ich nur cityStatistics die aid's enthalten die auch cid's sind, muß ich
[./organization/cid = ./financial/aid]  auf cityStatistics-Ebene definieren.

Die XPath im Prädikat sind relativ zur aktuellen Ebene.
Das Gleichheitszeichen für Sequenzen von Knoten (P: X=Y)
hat laut XQuery some-x-satisfies-P-Semantik.
D.h. der Vergleich evaluiert zu true genau dann, wenn  es ein x in X gibt für das
P (x=y) gilt bzw es ein y in Y gibt für das P (y=x) gilt.

Im Gegensatz dazu evaluiert die every-x-satisfies-P-Semantik zu true,
genau dann wenn P für alle x gilt.
Somit ist die every-x-satisfies-P-Semantik wie folgt auszudrücken:
every $n in ./organization/cid satisfies ./financial/aid = $n
every $n in ./financial/aid satisfies ./organization/cid = $n

Will ich (optional) nur die Elemente ausgeben, auf die das obige Join-Prädikat
zutrifft, muß ich dies auf der entsprechenden Elementebene definieren:
[./../../financial/aid = .] auf der Ebene der cid
und
[./../../organization/cid = .] auf der Ebene der aid
Auch hier wirkt die Selektion nur auf der Definitionsebene.

Somit ist ein Join-Prädikat nur ein Prädikat neben anderen und wird
analog behandelt.

Future Work (Predicate-Editor):
Ist der Join bei den Elementen selbst (cid=x und x=aid) vereinbart,
so gilt er global für diese Elemente
==> analog zu [./cityStatistics/organization/cid = ./cityStatistics/financial/aid]
auf der Ebene von "statisticsDB" (weil statisticsDB root ist)
<result>
{
for $k in document("statisticsDB.xml")/statisticsDB/*
where local-name( $k ) = 'cityStatistics'
(:some-Semantik:)
and $k/organization/cid = $k/financial/aid
(:every-Sematik:)
and every $n in $k/organization/cid satisfies $k/financial/aid = $n
and every $n in $k/financial/aid satisfies $k/organization/cid = $n
return
element { node-name ( $k ) } {
for $i in $k/*
where local-name( $i ) = 'organization' or local-name( $i ) = 'financial'
return
   (
   if ( local-name( $i ) = 'organization' ) then
      for $j in $i/*
      where local-name( $j ) = 'cid'
      and $j/../../financial/aid = $j (:nur die, die auch joinen:)
      return
         $j
   else (),
   if ( local-name( $i ) = 'financial' ) then
      for $j in $i/*
      where local-name( $j ) = 'aid'
      and $j/../../organization/cid = $j (:nur die, die auch joinen:)
      return
         $j
   else ()
   )
}
}
</result>


18
17
"cid" und "aid" innerhalb EINER cityStatistics joinen

[./organization/cid = ./financial/aid]
auf Ebene von "cityStatistics"
===> Selektion auf "cityStatistics"


- alle "cid"s und "aid"s die in einer "cityStatistics" stehen, die mindestens eine cid hat die auch aid ist (some-Semantik)

- in Document-Order
---------------------------------------------
so, dass nur die cityStatistics ausgewertet werden,
bei denen cid und aid gleich
---------------------------------------------

<result>
{
for $k in document("statisticsDB.xml")/statisticsDB/*
where local-name( $k ) = 'cityStatistics'
and $k/organization/cid = $k/financial/aid
return
for $i in $k/*
where local-name( $i ) = 'organization' or local-name( $i ) = 'financial'
return
   (
   if ( local-name( $i ) = 'organization' ) then
      for $j in $i/*
      where local-name( $j ) = 'cid'
      return
         $j
   else (),
   if ( local-name( $i ) = 'financial' ) then
      for $j in $i/*
      where local-name( $j ) = 'aid'
      return
         $j
   else ()
   )
}
</result>



alle Werte einer cityStatistics bei der es mindestens ein
cid-aid-paar (MSFT) gibt
---------------------------------------------

      <result>
         <cid>MSFT</cid>
         <aid>Sk31(SQLServer12350G006MicrosoftRedmondMSFT)</aid>
         <aid>MSFT</aid>
         <aid>HP</aid>
         <aid>Sk31(Leo500G005MicrosoftRedmondMSFT)</aid>
      </result>



19
24
"cid" und "cname" innerhalb EINER organization joinen

[./cid = ./cname]
auf Ebene von "organization"
===> Selektion auf "organization"

- alle "cid"s einer organization, wobei die organisation mindestens eine "cid" haben muß, die auch "cname" ist

- alle "amout"s (unabhängig)

- in Document-Order

so, dass nur die organizations ausgewertet werden,
bei denen mindestens ein cid und cname gleich
---------------------------------------------

<result>
{
for $i in document("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name( $i ) = 'organization' and $i/cid = $i/cname
or local-name( $i ) = 'financial'
return
(
if ( local-name( $i ) = 'organization' ) then
for $k in $i/*
where local-name( $k ) = 'cid'
return
$k
else (),
if ( local-name( $i ) = 'financial' ) then
for $j in $i/*
where local-name( $j ) = 'amount'
return
$j
else ()
)
}
</result>
      <result>
<amount>12350</amount>
<amount>12350</amount>
<amount>12350</amount>
<amount>500</amount>
<cid>IBMInternational Business Machines</cid>
<amount>3500</amount>
<amount>25000</amount>
<amount>5000</amount>
<amount>10000</amount>
</result>



Future Work


20
17
cid als a definiert
a = aid (join zwischen cid und aid)

- alle "cid"s die eine korrespondierende "aid" haben

- alle "aid"s die eine korrespondierende "cid" haben

- in Document-Order
<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name($i) = 'organization' or local-name($i) = 'financial'
return (
if ( local-name( $i ) = 'organization' ) then
for $k in $i/*
where local-name($k) = 'cid'
and some $n in doc("statisticsDB.xml")/statisticsDB/cityStatistics/financial/aid satisfies $n = $k
return
$k
else (),
if (local-name( $i ) = 'financial' ) then
for $k in $i/*
where local-name($k) = 'aid'
and some $n in doc("statisticsDB.xml")/statisticsDB/cityStatistics/organization/cid satisfies $n = $k
return
$k
else ()
)
}
</result>


      <result>
         <cid>MSFT</cid>
         <aid>MSFT</aid>
      </result>
21
18
cid als a definiert
a = aid (join zwischen cid und aid)

- alle "cid"s die eine korrespondierende "aid" haben

- alle "amount"s (unabhängig von der aid)

- in Document-Order

<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name($i) = 'organization' or local-name($i) = 'financial'
return (
if ( local-name( $i ) = 'organization' ) then
for $k in $i/*
where local-name($k) = 'cid'
and some $n in doc("statisticsDB.xml")/statisticsDB/cityStatistics/financial/aid satisfies $n = $k
return
$k
else (),
if (local-name( $i ) = 'financial' ) then
for $k in $i/*
where local-name($k) = 'amount'
return
$k
else ()
)
}
</result>

      <result>
         <cid>MSFT</cid>
         <amount>12350</amount>
         <amount>12350</amount>
         <amount>12350</amount>
         <amount>500</amount>
         <amount>3500</amount>
         <amount>25000</amount>
         <amount>5000</amount>
         <amount>10000</amount>
      </result>

22
19
cid als a definiert
a = aid (join zwischen cid und aid)

- alle "cid"s die eine korrespondierende "aid" haben

- alle "amount"s (unabhängig von der aid)

- alle "city"s

- in Document-Order
<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name($i) = 'organization' or local-name($i) = 'financial' or local-name($i) = 'city'
return (
if ( local-name( $i ) = 'organization' ) then
for $k in $i/*
where local-name($k) = 'cid'
and some $n in doc("statisticsDB.xml")/statisticsDB/cityStatistics/financial/aid satisfies $n = $k
return
$k
else (),
if (local-name( $i ) = 'financial' ) then
for $k in $i/*
where local-name($k) = 'amount'
return
$k
else (),
if (local-name( $i ) = 'city' ) then
$i
else ()
)
}
</result>
------------------------------------------------------------
falsch, da auch amounts von aid abhängig gemacht werden
------------------------------------------------------------
<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name($i) = 'organization' or local-name($i) = 'financial' or local-name($i) = 'city'
return (
if ( local-name( $i ) = 'organization' ) then
for $k in $i/*
where local-name($k) = 'cid'
return
for $l in doc("statisticsDB.xml")/statisticsDB/cityStatistics/financial/aid
where $l = $i/cid
return
$k
else (),
if (local-name( $i ) = 'financial' ) then
for $k in $i/*
where local-name($k) = 'amount'
return
for $l in doc("statisticsDB.xml")/statisticsDB/cityStatistics/organization/cid
where $l = $i/aid
return
$k
else (),
if (local-name( $i ) = 'city' ) then
$i
else ()
)
}
</result>

      <result>
         <cid>MSFT</cid>
         <amount>12350</amount>
         <amount>12350</amount>
         <amount>12350</amount>
         <amount>500</amount>
         <city>Redmond</city>
         <amount>3500</amount>
         <amount>25000</amount>
         <amount>5000</amount>
         <amount>10000</amount>
         <city>San Jose</city>
      </result>

23 20
cid als a definiert
a = aid (join zwischen cid und aid)

- alle "cid"s die eine korrespondierende "aid" haben

- alle "financials"s mit ggf. vorhandenen "myattribute"-Attributen
(unabhängig von der aid)

- in Document-Order
<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name($i) = 'organization' or local-name($i) = 'financial'
return (
if ( local-name( $i ) = 'organization' ) then
for $k in $i/*
where local-name($k) = 'cid'
and some $n in doc("statisticsDB.xml")/statisticsDB/cityStatistics/financial/aid satisfies $n = $k
return
$k
else (),
if (local-name( $i ) = 'financial' ) then
(: mit if-abfrage, ob das attribut überhaupt existiert ???!!!??? :)
element { node-name($i) }
{ $i/@myattribute }
else ()
)
}
</result>


<result>
    <cid>MSFT</cid>
    <financial myattribute="christoph"/>
    <financial myattribute="christoph"/>
    <financial myattribute="christoph"/>
    <financial myattribute="robert"/>
    <financial/>
    <financial/>
    <financial/>
    <financial/>
</result>

24 21
aid = 'MSFT'

- alle "aid"s die den Wert ''MSFT" haben

- in Document-Order
<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/financial/*
where local-name($i) = 'aid'
and $i = 'MSFT'
return $i
}
</result>


25
22
cid als a definiert
a = aid (join zwischen cid und aid)

- alle "financial"s mit ihren "aid"s und "amount"s,
wobei (nur) die  "aid"s eine korrespondierende "cid" haben müssen

- in Document-Order
<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name( $i ) = 'financial'
return
element { node-name( $i ) } {
for $j in $i/*
where local-name( $j ) = 'amount'
or local-name( $j ) = 'aid'
and some $n in doc("statisticsDB.xml")/statisticsDB/cityStatistics/organization/cid satisfies $n = $j
return
$j
}
}
</result>
----------------------------------------------------------------------------
mit "let" zu lang und kompliziert ...
----------------------------------------------------------------------------
<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name( $i ) = 'financial'
return
element { node-name( $i ) } {
for $j in $i/*
let $l := doc("statisticsDB.xml")/statisticsDB/cityStatistics/organization[cid = $j]
where local-name( $j ) = 'aid' or local-name( $j ) = 'amount'
return
(
if ( local-name( $j ) = 'aid') then
if (not(empty( $l ))) then
$j
else ()
else (),
if ( local-name( $j ) = 'amount' ) then
$j
else ()
)
}
}
</result>
--------------------------------------------------------------------------------
falsch, da durch for für join im falle dass es mehrere passende cid's gibt, die aid mehrfach ausgegeben wird
--------------------------------------------------------------------------------
<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name( $i ) = 'financial'
return
element { node-name( $i ) } {
for $j in $i/*
where local-name( $j ) = 'aid' or local-name( $j ) = 'amount'
return
(
if ( local-name( $j ) = 'aid' ) then
for $k in doc("statisticsDB.xml")/statisticsDB/cityStatistics/organization/cid
where $k = $i/aid
return
$j
else (),
if ( local-name( $j ) = 'amount' ) then
$j
else ()
)
}
}
</result>


<result>
  <financial>
    <amount>12350</amount>
  </financial>
  <financial>
    <aid>MSFT</aid>
    <amount>12350</amount>
  </financial>
  <financial>
    <amount>12350</amount>
  </financial>
  <financial>
    <amount>500</amount>
  </financial>
  <financial>
    <amount>3500</amount>
  </financial>
  <financial>
    <amount>25000</amount>
  </financial>
  <financial>
    <amount>5000</amount>
  </financial>
  <financial>
    <amount>10000</amount>
  </financial>
</result>

















Allgemeines zu Order By:

"Order By" kann nur auf  Simple-Type-Elemente und Attribute angewendet werden.
Innerhalb einer Ebene können immer nur alle auszugebenen SimpleType-Elemente sortiert werden: Soll z.Bsp.: "gid" und "proj" unterhalb von "funding" ausgeben sowie sortiert werden,  wird das Ergebnis eine lexikogrphisch sortierte Liste von "gid"- und "proj"-Elementen.
Elemente die einen komplexen Typ haben, können nur nach entsprechenden (Simple-Type-Elemente / Attribute) Kindern sortiert werden.

Was die Implementation betrifft, werden wir im ersten Schritt die nachfolgend beschriebene Variante umsetzen. Hierbei ist zu beachten, das sich die Anwendung der order-by-Klausel am bisherigen Schema-F der XQuery orientiert. Dies hat zur Folge, das sich der Scope einer Order eines Simple-Elements immer auf einen komplexen Vorfahren bezieht - je nach restlicher Query. Dieser Scope muß in zukünftigen Versionen frei definierbar sein.


28

an "proj" oder "faid" oder "recv" steht
"ORDER BY ." oder "ORDER"
-SORTIERTE Liste von "proj", "faid" oder "reciv"-Elementen.

<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/
cityStatistics/organization/funding/*
where local-name( $i ) = 'proj'
or local-name( $i ) = 'faid'
or local-name( $i ) = 'recv'
order by $i
return
$i
}
</result>


<result>
<recv>Blablabla</recv>
<proj>Clio</proj>
<proj>Clio</proj>
<proj>DB2</proj>
<proj>FastNetwork</proj>
<proj>Leo</proj>
<proj>SQLServer</proj>
<faid>Sk31(Clio10000G003International Business MachinesSan JoseIBM)</faid>
<faid>Sk31(Clio3500G004International Business MachinesSan JoseIBM)</faid>
<faid>Sk31(DB225000G001International Business MachinesSan JoseIBM)</faid>
<faid>Sk31(FastNetwork5000G007Network AssociatesSan JoseNA)</faid>
<faid>Sk31(Leo500G005MicrosoftRedmondMSFT)</faid>
<faid>Sk31(SQLServer12350G006MicrosoftRedmondMSFT)</faid>
</result>
29

an "funding" steht "ORDER BY ./proj"

- nach "proj" SORTIERTE Liste von ["proj" / "faid" / "reciv"]-Tripeln (Gruppierung nach "funding" wird - aber nicht ausgeben)

<result>
{
for $j in doc("statisticsDB.xml")/statisticsDB/
cityStatistics/organization/*
where local-name( $j ) = 'funding'
order by $j/proj
return
for $i in $j/*
where local-name( $i ) = 'proj'
or local-name( $i ) = 'faid'
or local-name( $i ) = 'recv'
return
$i
}
</result>
<result>
<proj>Clio</proj>
<faid>Sk31(Clio3500G004International Business MachinesSan JoseIBM)</faid>
<proj>Clio</proj>
<faid>Sk31(Clio10000G003International Business MachinesSan JoseIBM)</faid>
<proj>DB2</proj>
<faid>Sk31(DB225000G001International Business MachinesSan JoseIBM)</faid>
<proj>FastNetwork</proj>
<faid>Sk31(FastNetwork5000G007Network AssociatesSan JoseNA)</faid>
<proj>Leo</proj>
<faid>Sk31(Leo500G005MicrosoftRedmondMSFT)</faid>
<recv>Blablabla</recv>
<proj>SQLServer</proj>
<faid>Sk31(SQLServer12350G006MicrosoftRedmondMSFT)</faid>
</result>
30
25
an "cname" steht "ORDER"

- NICHT lesen, bevor man nicht selbst über diesen fall nachgedacht hat






- alle "cname"s SORTIERT (untereinander in nächst höherem Element - "organization")
 ==> macht nur Sinn. wenn eine "organization" mehrere "cname"s hat

- alle "amount"s

- in Document Order


===> schwierige Semantik
===> macht das Sinn ???
<result>
{
for $i in doc("statisticsDB.xml")/statisticsDB/cityStatistics/*
where local-name( $i ) = 'organization' or local-name( $i ) = 'financial'
return
(
if ( local-name( $i ) = 'organization' ) then
for $k in $i/*
where local-name( $k ) = 'cname'
order by $k
return
$k
else (),
if ( local-name( $i ) = 'financial' ) then
for $j in $i/*
where local-name( $j ) = 'amount'
return
$j
else ()
)
}
</result>
<result>
<cname>Microsoft</cname>
<amount>12350</amount>
<amount>12350</amount>
<amount>12350</amount>
<amount>500</amount>
<cname>IBMInternational Business Machines</cname>
<cname>Network Associates1</cname>
<cname>Network Associates2</cname>
<cname>Network Associates3</cname>
<amount>3500</amount>
<amount>25000</amount>
<amount>5000</amount>
<amount>10000</amount>
</result>

-----------------------------------------
Ergebnis ohne Sortierung
-----------------------------------------

<result>
<cname>Microsoft</cname>
<amount>12350</amount>
<amount>12350</amount>
<amount>12350</amount>
<amount>500</amount>
<cname>IBMInternational Business Machines</cname>
<cname>Network Associates3</cname>
<cname>Network Associates1</cname>
<cname>Network Associates2</cname>
<amount>3500</amount>
<amount>25000</amount>
<amount>5000</amount>
<amount>10000</amount>
</result>
31
25
an "cityStatistics" steht
"ORDER BY ./city"

- alle "cname"s
- alle "amount"s
- in Document Order

- "cityStatistics"-Gruppen von "cname"s bzw. "amount"s  die anhand der "cityStatistics/city" sortiert sind
- "cityStatistics" wird nicht ausgegeben
- innerhalb der Gruppen wird alles in Document Order ausgegeben

 ==> macht nur Sinn, wenn es mehrere cityStatistics gibt
 
==> funktioniert nur, WENN ES FÜR JEDE "cityStatistics" genau eine "CITY" gibt - sonst  "order key must be atomic" - FEHLER - den könnte man mit Schema-Informationen vermeiden

<result>
{
for $l in doc("statisticsDB.xml")/statisticsDB/*
where local-name( $l ) = 'cityStatistics'
order by $l/city
return
for $i in $l/*
where local-name( $i ) = 'organization' or local-name( $i ) = 'financial'
return
(
if ( local-name( $i ) = 'organization' ) then
for $k in $i/*
where local-name( $k ) = 'cname'
return
$k
else (),
if ( local-name( $i ) = 'financial' ) then
for $j in $i/*
where local-name( $j ) = 'amount'
return
$j
else ()
)
}
</result>


<result>
<cname>Microsoft</cname> ==> für Redmond
<amount>12350</amount>
<amount>12350</amount>
<amount>12350</amount>
<amount>500</amount>
<cname>IBMInternational Business Machines</cname> ==> für San Jose
<cname>Network Associates3</cname>
<cname>Network Associates1</cname>
<cname>Network Associates2</cname>
<amount>3500</amount>
<amount>25000</amount>
<amount>5000</amount>
<amount>10000</amount>
</result>
32
26
an "cityStatistics" steht
"ORDER BY ./city"
- alle "cname"s - in Document Order
- alle "amount"s - in Document Order
- gruppiert nach "cityStatistics" die sortiert sind nach "city"s


- "cityStatistics"-Gruppen von "cname"s bzw. "amount"s  die anhand der "cityStatistics/city" sortiert sind
- innerhalb der Gruppen wird alles in Document Order ausgegeben

 ==> macht nur Sinn, wenn es mehrere cityStatistics gibt

 ==> funktioniert nur, WENN ES FÜR JEDE "cityStatistics" genau eine "CITY" gibt - sonst  "order key must be atomic" - FEHLER
<result>
{
for $l in doc("statisticsDB.xml")/statisticsDB/*
where local-name( $l ) = 'cityStatistics'
order by $l/city
return
element { node-name( $l ) } {
for $i in $l/*
where local-name( $i ) = 'organization' or local-name( $i ) = 'financial'
return
(
if ( local-name( $i ) = 'organization' ) then
for $k in $i/*
where local-name( $k ) = 'cname'
return
$k
else (),
if ( local-name( $i ) = 'financial' ) then
for $j in $i/*
where local-name( $j ) = 'amount'
return
$j
else ()
)
}
}
</result>
<result>
<cityStatistics>
<cname>Microsoft</cname>
<amount>12350</amount>
<amount>12350</amount>
<amount>12350</amount>
<amount>500</amount>
</cityStatistics>
<cityStatistics>
<cname>IBMInternational Business Machines</cname>
<cname>Network Associates3</cname>
<cname>Network Associates1</cname>
<cname>Network Associates2</cname>
<amount>3500</amount>
<amount>25000</amount>
<amount>5000</amount>
<amount>10000</amount>
</cityStatistics>
</result>
33
26
an "cityStatistics" steht
"ORDER BY ./organization/cid"

- wie Fall darüber - aber andere Sortierung

==> geht nicht, da es pro "cityStatistics" mehrere "organzation" mit "cid" gibt:



<result>
{
   for $l in doc("statisticsDB.xml")/statisticsDB/*
   where local-name( $l ) = 'cityStatistics'
   return
      element { node-name( $l ) } {
         count($l/organization)
      }
}
</result>
---------------------------------
hat zur Antwort:
---------------------------------
<result>
  <cityStatistics>1</cityStatistics>
  <cityStatistics>2</cityStatistics>
</result>

---------------------------------
deshalb:
---------------------------------
*** in query.xq, at line 5: order key must be atomic
order by $l/organization/cid
------------^

<result>
{
for $l in doc("statisticsDB.xml")/statisticsDB/*
where local-name( $l ) = 'cityStatistics'
order by $l/organization/cid
return
element { node-name( $l ) } {
for $i in $l/*
where local-name( $i ) = 'organization' or local-name( $i ) = 'financial'
return
(
if ( local-name( $i ) = 'organization' ) then
for $k in $i/*
where local-name( $k ) = 'cname'
return
$k
else (),
if ( local-name( $i ) = 'financial' ) then
for $j in $i/*
where local-name( $j ) = 'amount'
return
$j
else ()
)
}
}
</result>



*** in query.xq, at line 5: order key must be atomic
order by $l/organization/cid
------------^
in main query in query.xq, line 5
34




35