2

我是 Xquery 的初学者,我有一个 xml 代码,我想在其中将两个不同的 XML 文件与另一个文件相关联。

书本.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>

作者.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
4

2 回答 2

3

您的代码存在多个较小的问题。

  1. 作者和书籍 XML 文件中的姓名不匹配。我想这只是一些错别字。
  2. 谓词属于一个轴步骤,而不是它们自己的(删除第一行之后的斜线book)。
  3. XML 和 XQuery 对大小写敏感!<Book/>使用大写字母 B,所以在您的 XQuery 中也这样做,同样在第 1 行。
  4. 在第二行中,您循环遍历所有<authorRoot/>元素。改为使用authorRoot/author
  5. 在第 3 行中,您在$pFLWOR 表达式的其余部分中隐藏了带有书名的书,但您想在第 5 行中再次使用这本书。最好使用另一个变量名。
  6. 如果不需要,最好不要使用descendant-or-self-step //(第一行和第二行)。这会降低性能。

我不明白您在第三到第五行中对过滤的想法是什么。将您自己与此工作解决方案进行比较。此外,我使用了口语变量名称,不要将自己与不必要的短名称混淆。

替换$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 处理器。

于 2013-11-27T12:30:07.527 回答
2

如果你使用

let $books := <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>
let $authors := <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>
     <author>
         <Name>Ellizabith</Name>
         <Location>Apple</Location>
    </author>
    </authorRoot>
    return $authors/author[Name = $books/Book[contains(title, 'Title1')]/author]/Location/string()

结果是Apple

于 2013-11-27T12:29:25.043 回答