XQuery多个xml文件?

时间:2009-01-27 16:51:35

标签: xml xquery

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

3 个答案:

答案 0 :(得分:10)

是的,此处an example来自XQuery spec

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

  1. 包含许多parts.xml元素的名为part的文档;每个part元素又包含partnodescription子元素。
  2. 包含许多suppliers.xml元素的名为supplier的文档;每个supplier元素又包含suppnosuppname子元素。
  3. 名为catalog.xml的文档,其中包含有关供应商和零件之间关系的信息。目录文档包含许多item元素,每个元素又包含partnosuppnoprice子元素。
  4. 传统(“内部”)联接返回来自两个或多个相关来源的信息,如以下示例所示,该示例组合了来自三个文档的信息。该示例生成从目录文档派生的“描述性目录”,但包含部件描述而不是部件号和供应商名称而不是供应商编号。新目录按部件描述按字母顺序排序,其次按供应商名称排序。*

    <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 function),而是具有doc()函数,它是“{3}}函数的一部分。 XQuery 1.0 and XPath 2.0 Functions and Operators”。

    Chris 的答案中至少有两个错误:

    1. XQuery is case sensitive - 符合规范的XQuery处理器不允许使用Chris示例中使用的大写关键字。
    2. 没有必要像doc()那样添加标准函数前缀,我只是引用了带有前缀的XQuery规范。否则,在我自己的代码中,我将省略“fn”前缀。
    3. 函数document()不是标准的XQuery / XPath函数。应该使用doc()函数。

答案 1 :(得分:1)

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

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

for $x in $items ...

答案 2 :(得分: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执行连接。