我是 Xquery 的初学者,我有一个 xml 代码,我想在其中将两个不同的 XML 文件与另一个文件相关。
Book.xml
<library>
<Book>
<title>Title1</title>
<author>Ellizabith</author>
</Book>
<Book>
<title>Title2</title>
<author>Sam</author>
</Book>
<Book>
<title>Title3</title>
<author>Ryan</author>
</Book>
</library>
author.xml
<authorRoot>
<author>
<Name>Rayan</Name>
<Location>Yahoo</Location>
</author>
<author>
<Name>Syan</Name>
<Location>Google</Location>
</author>
<author>
<Name>Sam</Name>
<Location>Bing</Location>
</author>
</authorRoot>
在此答案中,查询显示标题包含单词“Title2”的书籍的所有作者的位置。
这是我的代码:
for $p in doc("C:\Users\User\Desktop\Book.xml")//library/book/[title/contains(., 'Title1')]
for $a in doc("C:\Users\User\Desktop\author.xml")//authorRoot
let $p := $p/author/text()
let $d := $a/author
let $f := $d/text()=$p/Location/text()
return $f
最佳答案
您的代码存在多个较小的问题。
- 作者和书籍 XML 文件中的姓名不匹配。我想这只是一些错别字。
- 谓词属于一个轴步骤,而不是它们自己的步骤(删除第一行
book
后面的斜杠)。 - XML 和 XQuery 区分大小写!
<Book/>
使用大写 B,因此在 XQuery 中执行相同的操作(同样在第 1 行中)。 - 在第二行中,您循环遍历所有
<authorRoot/>
元素。使用authorRoot/author
相反。 - 在第三行中,您隐藏了这本书
$p
FLWOR 表达式其余部分的名称,但您想在第五行再次使用这本书。最好使用另一个变量名。 - 最好不要使用
descendant-or-self
-步骤//
如果您不需要它(第一行和第二行)。这会降低性能。
我不明白您的过滤想法在第三行到第五行中是什么。将自己与这个可行的解决方案进行比较。另外,我使用了口语变量名称,不要将自己与不必要的短变量名称混淆。
替换$book
和$authors
由尊敬的doc(...)
功能。
for $book in $books//library/Book[title/contains(., 'Title1')]
for $author in $authors//authorRoot/author
where $book/author = $author/Name
return $author/Location/text()
如果您想要一个不同地点的列表,请将 distinct-values(...)
括起来围绕所有四行。
没有显式循环的替代方案:
$authors/authorRoot/author[
Name = $books/library/Book[contains(title, 'Title1')]/author)
]/Location
第二个解决方案也是有效的 XPath 1.0,第一个解决方案需要 XPath 3.0 或 XQuery 处理器。
关于xpath - 从两个依赖的 xml 文件获取节点值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20237911/