xml - create - xquery let
XQuery mĂșltiples archivos xml? (3)
¿Es posible abrir 2 documentos de un xQuery y unirse en ellos?
Sí, aquí hay un ejemplo de la especificación XQuery .
"Las combinaciones, que combinan datos de múltiples fuentes en un solo resultado, son un tipo de consulta muy importante. En esta sección, ilustraremos cómo se pueden expresar varios tipos de combinaciones en XQuery. Basaremos nuestros ejemplos en los siguientes tres documentos:
- Un documento llamado
parts.xml
que contiene muchos elementos depart
; cada elemento depart
a su vez contiene subelementos departno
ydescription
. - Un documento llamado
suppliers.xml
que contiene muchos elementos desupplier
; cada elemento desupplier
a su vez contiene subelementossuppno
ysuppname
. - Un documento llamado
catalog.xml
que contiene información sobre las relaciones entre proveedores y partes. El documento de catálogo contiene muchositem
elementos, cada uno de los cuales contiene a su vezprice
subelementospartno
,suppno
yprice
.
Una combinación convencional ("interna") devuelve información de dos o más fuentes relacionadas, como se ilustra en el siguiente ejemplo, que combina información de tres documentos. El ejemplo genera un "catálogo descriptivo" derivado del documento del catálogo, pero que contiene descripciones de piezas en lugar de números de parte y nombres de proveedores en lugar de números de proveedor. El nuevo catálogo se ordena alfabéticamente por descripción de la parte y, en segundo lugar, por nombre del proveedor. *
<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>
La consulta anterior devuelve información solo sobre las partes que tienen proveedores y proveedores que tienen partes. Una combinación externa es una combinación que conserva información de una o más de las fuentes participantes, incluidos los elementos que no tienen ningún elemento coincidente en la otra fuente. Por ejemplo, una combinación externa izquierda entre proveedores y partes puede devolver información sobre proveedores que no tienen partes coincidentes ".
Tenga en cuenta que XQuery no tiene una función document () estándar ( es una función XSLT ) y, en su lugar, tiene la función doc () , que es parte de " XQuery 1.0 y XPath 2.0 Functions and Operators ".
Hay al menos dos errores en la respuesta de Chris :
- XQuery distingue entre mayúsculas y minúsculas : las palabras clave en mayúscula utilizadas en el ejemplo de Chris no serán permitidas por un procesador XQuery conforme.
- No es necesario prefijar las funciones estándar como doc (), solo estoy citando la especificación XQuery, que tiene el prefijo. De lo contrario, en mi propio código omitiría el prefijo "
fn
". - El documento de función () no es una función XQuery / XPath estándar . La función doc () debe usarse en su lugar.
En XQuery, si escribe algo como lo siguiente:
for $x in doc(''doc1.xml'')//a
for $y in doc(''doc2.xml'')//a
where $x/@name = $y/@name
return $x
entonces su procesador XQuery debe ser lo suficientemente inteligente como para detectar que se trata de una unión.
Nunca especificas explícitamente en XQuery que algo es una unión. El tema común en XQuery es que su programa dice qué información quiere, no cómo calcularla.
Aunque puede parecer que estás recorriendo repetidamente el segundo documento en la práctica, un procesador XQuery real lo haría de forma más inteligente, aproximadamente análoga a la siguiente instrucción SQL (mi SQL está muy oxidado, así que me disculpo si esta sintaxis es completamente incorrecta).
SELECT doc1.a
FROM doc1 INNER JOIN doc2
WHERE doc1.name = doc2.name
El benchmark de XMark contiene varias consultas de muestra, estas valen la pena. En particular, las consultas 9 a 12 realizan uniones.
es más fácil que eso (al menos usando SAXON):
let $items := (
doc("file1.xml") ,
doc("file2.xml") ,
doc("file3.xml")
)
for $x in $items ...