Frage
Ist es möglich, zwei Dokumente von einem xQuery zu öffnen und ihnen eine Verknüpfung tun?
Lösung
Ja, hier ist ein Beispiel aus dem XQuery spec .
"Joins, die Daten aus mehreren Quellen in ein einziges Ergebnis kombiniert, ist eine sehr wichtige Art der Abfrage. In diesem Abschnitt erläutern wir, wie verschiedene Arten von Joins in XQuery ausgedrückt werden. Wir werden unsere Beispiele auf dem folgende Basis drei Dokumente:
- Ein Dokument mit dem Namen
parts.xml
, die vielepart
Elemente enthält; jedespart
Element enthält wiederumpartno
unddescription
Subelementen. - Ein Dokument mit dem Namen
suppliers.xml
, die vielesupplier
Elemente enthält; jedessupplier
Element enthält wiederumsuppno
undsuppname
Subelementen. - Ein Dokument mit dem Namen
catalog.xml
, die Informationen über die Beziehungen zwischen Lieferanten und Teile enthält. Der Katalog Dokument enthält vieleitem
Elemente, von denen jeder wiederum enthältpartno
,suppno
undprice
Subelementen.
Ein herkömmlicher ( „innere“) verbinden gibt Informationen aus zwei oder mehreren verwandten Quellen, wie durch das folgende Beispiel veranschaulicht, die Information von drei Dokumenten kombiniert. Das Beispiel erzeugt einen „Beschreibungs Katalog“ aus dem Katalog Dokument abgeleitet ist, sondern Teil Beschreibungen anstelle von Teilenummern und Lieferantennamen anstelle von Lieferantennummern enthält. Der neue Katalog ist alphabetisch nach Teilebeschreibung geordnet und in zweiter Linie durch Lieferantennamen. *
<descriptive-catalog>
{
for $i in fn:doc("catalog.xml")/items/item,
$p in fn:doc("parts.xml")/parts/part[partno = $i/partno],
$s in fn:doc("suppliers.xml")/suppliers
/supplier[suppno = $i/suppno]
order by $p/description, $s/suppname
return
<item>
{
$p/description,
$s/suppname,
$i/price
}
</item>
}
</descriptive-catalog>
Die vorherige Abfrage gibt nur Informationen über Teile, die Lieferanten und Zulieferer, die Teile haben. An äußere Verknüpfung ist eine Verknüpfung, die Informationen von einer oder mehreren der beteiligten Quellen erhält, einschließlich der Elemente, die keine passenden Element in der anderen Quelle. Zum Beispiel kann ein linke äußere zwischen Lieferanten und Teile könnten Informationen zu Lieferanten zurückgeben, die keine Übereinstimmungen Teile haben. "
beachten Sie, dass XQuery () Funktion nicht ein Standarddokument hat (es ist ein XSLT-Funktion ) und stattdessen hat die doc () Funktion, die ein Teil des lautet " XQuery 1.0 und XPath 2.0 Funktionen und Operatoren “.
Es gibt mindestens zwei Fehler in der Antwort von Chris :
- Groß- und Kleinschreibung - die aktivierten Keywords in Chris' Beispiel verwendet werden nicht von einem konformen XQuery-Prozessor erlaubt werden.
- Es ist nicht erforderlich, die Standardfunktionen wie doc () voranstellen, ich zitiere nur die XQuery-Spezifikation, die das Präfix hat. Ansonsten in meinem eigenen Code würde ich den „
fn
“ Präfix weglassen. - Die Funktion document () ist kein Standard XQuery / XPath-Funktion . Die doc () sollte Funktion sein statt. verwendet
Andere Tipps
Es ist leichter als die (zumindest mit SAXON):
let $items := (
doc("file1.xml") ,
doc("file2.xml") ,
doc("file3.xml")
)
for $x in $items ...
In XQuery, wenn Sie so etwas wie die folgenden schreiben:
for $x in doc('doc1.xml')//a
for $y in doc('doc2.xml')//a
where $x/@name = $y/@name
return $x
dann XQuery-Prozessor sollte klug genug sein, zu erkennen, dass dies eine beizutreten.
Sie nie explizit in XQuery angeben, dass etwas ist eine Verknüpfung. Das gemeinsame Thema in XQuery ist, dass Ihr Programm sagt was Informationen, die Sie wollen, nicht wie es zu berechnen.
Auch wenn es, wie Sie über das zweite Dokument in der Praxis immer wieder Looping sind aussehen kann ein echter XQuery-Prozessor durchführen würde dies intelligente, etwa analog zu der folgenden SQL-Anweisung (mein SQL sehr rostig ist so entschuldige ich mich, wenn diese Syntax völlig falsch ist )
SELECT doc1.a
FROM doc1 INNER JOIN doc2
WHERE doc1.name = doc2.name
Die XMark Benchmark enthält mehrere Beispielabfragen, sind diese auch einen Blick wert. Insbesondere Abfragen 9 bis 12 durchführen verbindet.