8

是否可以从 xQuery 打开 2 个文档并对它们进行连接?

4

3 回答 3

11

是的,这是XQuery 规范中的一个示例。:

“联接将来自多个源的数据组合成一个结果,是一种非常重要的查询类型。在本节中,我们将说明如何在 XQuery 中表达几种类型的联接。我们将基于以下三个文档来举例说明:

  1. parts.xml包含许多part元素的命名文档;每个part元素依次包含partnodescription子元素。
  2. suppliers.xml包含许多supplier元素的命名文档;每个supplier元素依次包含suppnosuppname子元素。
  3. catalog.xml包含有关供应商和零件之间关系的信息的命名文档。目录文档包含许多item元素,每个元素又包含partnosuppnoprice子元素。

常规(“内部”)连接返回来自两个或多个相关源的信息,如下面的示例所示,它结合了来自三个文档的信息。该示例生成从目录文档派生的“描述性目录”,但包含部件描述而不是部件编号和供应商名称而不是供应商编号。新目录按零件描述的字母顺序排列,其次是供应商名称。*

<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 函数和运算符”的一部分。

克里斯的回答至少有两个错误

  1. XQuery区分大小写——在 Chris 的示例中使用的大写关键字将不会被符合标准的 XQuery 处理器所允许。
  2. 不需要像 doc() 这样的标准函数前缀,我只是引用了带有前缀的 XQuery 规范。否则,在我自己的代码中,我会省略“ fn”前缀。
  3. 函数 document() 不是标准的 XQuery/XPath 函数。应该改用doc()函数。
于 2009-01-27T18:10:22.573 回答
2

它比这更容易(至少使用 SAXON):

let $items := (
     doc("file1.xml") ,
     doc("file2.xml") ,
     doc("file3.xml")
)

for $x in $items ...
于 2012-10-25T14:35:45.793 回答
0

在 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 执行连接。

于 2009-01-27T18:08:26.087 回答