是否可以从 xQuery 打开 2 个文档并对它们进行连接?
3 回答
“联接将来自多个源的数据组合成一个结果,是一种非常重要的查询类型。在本节中,我们将说明如何在 XQuery 中表达几种类型的联接。我们将基于以下三个文档来举例说明:
parts.xml
包含许多part
元素的命名文档;每个part
元素依次包含partno
和description
子元素。suppliers.xml
包含许多supplier
元素的命名文档;每个supplier
元素依次包含suppno
和suppname
子元素。catalog.xml
包含有关供应商和零件之间关系的信息的命名文档。目录文档包含许多item
元素,每个元素又包含partno
、suppno
和price
子元素。
常规(“内部”)连接返回来自两个或多个相关源的信息,如下面的示例所示,它结合了来自三个文档的信息。该示例生成从目录文档派生的“描述性目录”,但包含部件描述而不是部件编号和供应商名称而不是供应商编号。新目录按零件描述的字母顺序排列,其次是供应商名称。*
<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>
前面的查询仅返回有关具有供应商的零件和具有零件的供应商的信息。外连接是保留来自一个或多个参与源的信息的连接,包括在另一个源中没有匹配元素的元素。例如,供应商和零件之间的左外连接可能会返回有关没有匹配零件的供应商的信息。”
请注意,XQuery 没有标准的 document() 函数(它是一个XSLT 函数),而是具有doc()函数,它是“ XQuery 1.0 和 XPath 2.0 函数和运算符”的一部分。
克里斯的回答至少有两个错误:
它比这更容易(至少使用 SAXON):
let $items := (
doc("file1.xml") ,
doc("file2.xml") ,
doc("file3.xml")
)
for $x in $items ...
在 XQuery 中,如果您编写如下内容:
for $x in doc('doc1.xml')//a
for $y in doc('doc2.xml')//a
where $x/@name = $y/@name
return $x
那么您的 XQuery 处理器应该足够聪明,可以发现这是一个连接。
您永远不会在 XQuery 中明确指定某事物是连接。XQuery 的共同主题是您的程序说明您想要什么信息,而不是如何计算它。
虽然看起来您在实践中重复循环第二个文档,但真正的 XQuery 处理器会更智能地执行此操作,大致类似于以下 SQL 语句(我的 SQL 非常生疏,因此如果此语法完全错误,我深表歉意)
SELECT doc1.a
FROM doc1 INNER JOIN doc2
WHERE doc1.name = doc2.name
XMark基准测试包含几个示例查询,这些非常值得一看。特别是查询 9 到 12 执行连接。