XQuery:"order by" 在 "for-each-pair" 中不起作用
XQuery: "order by" doesn't work in "for-each-pair"
我有 collection 1
个 xml 个文件。 collection中典型的xml文件如下:
典型的 XML 个文件来自 Collection 1
<book xml:id="1">
<body>
<collection>Name of collection 1</collection>
<title>Title of book</title>
<author>Author of book</author>
<date>Date of publication of book</date>
<text>This is a text of book .....</text>
</body>
</book>
我这样查询这些文件(我必须使用XQuery而不能在这里使用XSL,这超出了我的意愿。我的整个查询要复杂得多,这里我使用一个简单的版本来显示,充其量我的代码和我的问题):
来自 Collection 的 XML 个文件的 XQuery 1
for $book in collection("path_to_collection_1")
let $collection_name := data($book/collection)
let $title := data($book/title)
let $author := data($book/author)
let $date := data($book/date)
where $date >= '2000'
order by $date
return
<book>
<collection_name>{$collection_name}</collection_name>
<title>{$title}</title>
<author>{$author}</author>
<date>{$date}</date>
</book>
来自 Collection 1 XML 个文件的 XQuery 结果
(关注date
)
1
<book>
<collection_name>Collection 1</collection_name>
<title>This is a best novel in the word</title>
<author>Lebowski, Big</author>
<date>2001</date>
</book>
2
<book>
<collection_name>Collection 1</collection_name>
<title>Another greate book</title>
<author>Lincoln, Abraham</author>
<date>2005</date>
</book>
3
<book>
<collection_name>Collection 1</collection_name>
<title>The story of my life</title>
<author>Mouse, Mickey</author>
<date>2012</date>
</book>
etc. etc. etc.
好的,效果不错。
还有,我有一个collection 2
。第二个collection中的XML个文件和collection 1
中的文件基本一样,只是在结构上或一些节点的名字上有一些小的区别,所以我不得不使用不同的查询。
典型的 XML 个文件来自 Collection 2
<collection>
<this_is_book>
<data_about_book>
<name_of_collection>Name of collection 2</name_of_collection>
<title>Title of book</title>
<author>Author of book</author>
<date_of_publication>Date of publication of book</date_of_publication>
</data_about_book>
<text_of_book>
<text>This is a text of book.....</text>
</text_of_book>
</this_is_book>
</collection>
来自 Collection 的 XML 个文件的 XQuery 2
for $book in collection("path_to_collection_2")
let $collection_name := data($book//name_of_collection)
let $title := data($book//title)
let $author := data($book//author)
let $date := data($book//date_of_publication)
where $date >= '2000'
order by $date
return
<book>
<collection_name>{$collection_name}</collection_name>
<title>{$title}</title>
<author>{$author}</author>
<date>{$date}</date>
</book>
来自 Collection 2 XML 个文件的 XQuery 结果
(关注date
)
1
<book>
<collection_name>Collection 2</collection_name>
<title>Why I crossed the Rubicon river</title>
<author>Caesar, Julius</author>
<date>2003</date>
</book>
2
<book>
<collection_name>Collection 2</collection_name>
<title>Colonize it!</title>
<author>Musk, Elon</author>
<date>2007</date>
</book>
3
<book>
<collection_name>Collection 2</collection_name>
<title>I have no more imagination</title>
<author>Lennon, John</author>
<date>2011</date>
</book>
etc. etc. etc.
好的,效果不错。
我的第一个问题是合并两个查询的结果(我必须能够在同一个 XQuery 中查询两个 collection)。为此,我使用函数 for-each-pair
(这是我的另一个问题 的主题,非常感谢 Martin Honnen 的回答和建议)。
所以,我当前代码的简单架构如下:
for-each-pair(
collection("path_to_collection_1"),
collection("path_to_collection_2"),
function($collection1, $collection2) {
for $book in $collection1
... etc. (see above the whole query for 'collection 1')
,
for $book in $collection2
... etc. (see above the whole query for 'collection 2')
}
)
我目前的成绩
(关注date
)
1
<book>
<collection_name>Collection 1</collection_name>
<title>Another greate book</title>
<author>Lincoln, Abraham</author>
<date>2005</date>
</book>
2
<book>
<collection_name>Collection 1</collection_name>
<title>This is a best novel in the word</title>
<author>Lebowski, Big</author>
<date>2001</date>
</book>
3
<book>
<collection_name>Collection 1</collection_name>
<title>The story of my life</title>
<author>Mouse, Mickey</author>
<date>2012</date>
</book>
4
<book>
<collection_name>Collection 2</collection_name>
<title>Colonize it!</title>
<author>Musk, Elon</author>
<date>2007</date>
</book>
5
<book>
<collection_name>Collection 2</collection_name>
<title>Why I crossed the Rubicon river</title>
<author>Caesar, Julius</author>
<date>2003</date>
</book>
6
<book>
<collection_name>Collection 2</collection_name>
<title>I have no more imagination</title>
<author>Lennon, John</author>
<date>2011</date>
</book>
etc. etc. etc.
所以第二个查询的结果附加到第一个查询的结果。但是有一个问题:order by $date
子句不再起作用了...
我的问题和期望的结果:
至少。如何在每个结果中应用order by
子句?至少,我想要 result from collection 1 ordered by date
+ result from collection 2 ordered by date
.
充其量。 是否可以将 order by
子句应用于整个结果(即来自 collections 1 的组合结果和2)?充其量,我想要 result from collection 1 + result from collection 2 and then order all this by date
)?或者,为此,我必须完全改变我的方法并使用 for-each-pair
函数以外的其他东西?在这种情况下,哪个?
期望(最多)结果的示例。
(注意date
和collection_name
)
1
<book>
<collection_name>Collection 1</collection_name>
<title>This is a best novel in the word</title>
<author>Lebowski, Big</author>
<date>2001</date>
</book>
2
<book>
<collection_name>Collection 2</collection_name>
<title>Why I crossed the Rubicon river</title>
<author>Caesar, Julius</author>
<date>2003</date>
</book>
3
<book>
<collection_name>Collection 1</collection_name>
<title>Another greate book</title>
<author>Lincoln, Abraham</author>
<date>2005</date>
</book>
4
<book>
<collection_name>Collection 2</collection_name>
<title>Colonize it!</title>
<author>Musk, Elon</author>
<date>2007</date>
</book>
5
<book>
<collection_name>Collection 2</collection_name>
<title>I have no more imagination</title>
<author>Lennon, John</author>
<date>2011</date>
</book>
6
<book>
<collection_name>Collection 1</collection_name>
<title>The story of my life</title>
<author>Mouse, Mickey</author>
<date>2012</date>
</book>
etc. etc. etc.
非常感谢您的帮助!
编辑 1:
我以 order by date
为例。在实际代码中,我必须能够按 order by title
、order by author
等不同元素(由用户选择)进行排序(但我不需要应用许多不同的 orders by
同时。)所以,也许解决方案应该更“通用”,而不是特别依赖于 order by date
?
当每个项目遍历两个序列时,该函数将应用于每个项目。我认为您需要对 for-each-pair()
的前两个参数中发送的项目集合进行排序,而不是尝试执行一种排序,当它应用第三个参数的函数时,每个项目将是一个项目。
例如,使用一个函数,在该函数中您提供馆藏的名称来获取过滤后的书籍集,并按日期对两个馆藏进行排序作为前两个参数,然后第三个参数的函数简单地将项目和 returns 作为一个序列:
declare function local:sortByDate($path_to_collection) {
for $book in collection($path_to_collection)
let $collection_name := data($book//name_of_collection)
let $title := data($book//title)
let $author := data($book//author)
let $date := data($book//date_of_publication)
where $date >= '2000'
order by $date
return $book
};
for-each-pair(
local:sortByDate("path_to_collection_1"),
local:sortByDate("path_to_collection_2"),
function($collection1, $collection2) {
$collection1, $collection2
}
)
其实很简单。只需要将 for-each-pair
的组合结果作为序列放入变量中。然后循环遍历此序列的所有项目并根据需要对它们进行排序。瞧!
有这种方法的简单架构:
let $results_not_sorted := (
for-each-pair (
collection("path_to_collection_1"),
collection("path_to_collection_2"),
function($collection1, $collection2) {
for $book in $collection1
... etc. (see above the whole query for 'collection 1')
,
for $book in $collection2
... etc. (see above the whole query for 'collection 2')
}
)
)
for $result in $results_not_sorted
order by $result//date (:sort here by whatever you want)
return
$result
和详细代码:
let $results_not_sorted := (
for-each-pair (
collection("path_to_collection_1"),
collection("path_to_collection_2"),
function($collection1, $collection2) {
for $book in $collection1
let $collection_name := data($book/collection)
let $title := data($book/title)
let $author := data($book/author)
let $date := data($book/date)
where $date >= '2000'
return
<book>
<collection_name>{$collection_name}</collection_name>
<title>{$title}</title>
<author>{$author}</author>
<date>{$date}</date>
</book>
,
for $book in $collection2
let $collection_name := data($book//name_of_collection)
let $title := data($book//title)
let $author := data($book//author)
let $date := data($book//date_of_publication)
where $date >= '2000'
return
<book>
<collection_name>{$collection_name}</collection_name>
<title>{$title}</title>
<author>{$author}</author>
<date>{$date}</date>
</book>
}
)
)
for $result in $results_not_sorted
order by $result//date (:sort here by whatever you want)
return
$result
我有 collection 1
个 xml 个文件。 collection中典型的xml文件如下:
典型的 XML 个文件来自 Collection 1
<book xml:id="1">
<body>
<collection>Name of collection 1</collection>
<title>Title of book</title>
<author>Author of book</author>
<date>Date of publication of book</date>
<text>This is a text of book .....</text>
</body>
</book>
我这样查询这些文件(我必须使用XQuery而不能在这里使用XSL,这超出了我的意愿。我的整个查询要复杂得多,这里我使用一个简单的版本来显示,充其量我的代码和我的问题):
来自 Collection 的 XML 个文件的 XQuery 1
for $book in collection("path_to_collection_1")
let $collection_name := data($book/collection)
let $title := data($book/title)
let $author := data($book/author)
let $date := data($book/date)
where $date >= '2000'
order by $date
return
<book>
<collection_name>{$collection_name}</collection_name>
<title>{$title}</title>
<author>{$author}</author>
<date>{$date}</date>
</book>
来自 Collection 1 XML 个文件的 XQuery 结果
(关注date
)
1
<book>
<collection_name>Collection 1</collection_name>
<title>This is a best novel in the word</title>
<author>Lebowski, Big</author>
<date>2001</date>
</book>
2
<book>
<collection_name>Collection 1</collection_name>
<title>Another greate book</title>
<author>Lincoln, Abraham</author>
<date>2005</date>
</book>
3
<book>
<collection_name>Collection 1</collection_name>
<title>The story of my life</title>
<author>Mouse, Mickey</author>
<date>2012</date>
</book>
etc. etc. etc.
好的,效果不错。
还有,我有一个collection 2
。第二个collection中的XML个文件和collection 1
中的文件基本一样,只是在结构上或一些节点的名字上有一些小的区别,所以我不得不使用不同的查询。
典型的 XML 个文件来自 Collection 2
<collection>
<this_is_book>
<data_about_book>
<name_of_collection>Name of collection 2</name_of_collection>
<title>Title of book</title>
<author>Author of book</author>
<date_of_publication>Date of publication of book</date_of_publication>
</data_about_book>
<text_of_book>
<text>This is a text of book.....</text>
</text_of_book>
</this_is_book>
</collection>
来自 Collection 的 XML 个文件的 XQuery 2
for $book in collection("path_to_collection_2")
let $collection_name := data($book//name_of_collection)
let $title := data($book//title)
let $author := data($book//author)
let $date := data($book//date_of_publication)
where $date >= '2000'
order by $date
return
<book>
<collection_name>{$collection_name}</collection_name>
<title>{$title}</title>
<author>{$author}</author>
<date>{$date}</date>
</book>
来自 Collection 2 XML 个文件的 XQuery 结果
(关注date
)
1
<book>
<collection_name>Collection 2</collection_name>
<title>Why I crossed the Rubicon river</title>
<author>Caesar, Julius</author>
<date>2003</date>
</book>
2
<book>
<collection_name>Collection 2</collection_name>
<title>Colonize it!</title>
<author>Musk, Elon</author>
<date>2007</date>
</book>
3
<book>
<collection_name>Collection 2</collection_name>
<title>I have no more imagination</title>
<author>Lennon, John</author>
<date>2011</date>
</book>
etc. etc. etc.
好的,效果不错。
我的第一个问题是合并两个查询的结果(我必须能够在同一个 XQuery 中查询两个 collection)。为此,我使用函数 for-each-pair
(这是我的另一个问题
所以,我当前代码的简单架构如下:
for-each-pair(
collection("path_to_collection_1"),
collection("path_to_collection_2"),
function($collection1, $collection2) {
for $book in $collection1
... etc. (see above the whole query for 'collection 1')
,
for $book in $collection2
... etc. (see above the whole query for 'collection 2')
}
)
我目前的成绩
(关注date
)
1
<book>
<collection_name>Collection 1</collection_name>
<title>Another greate book</title>
<author>Lincoln, Abraham</author>
<date>2005</date>
</book>
2
<book>
<collection_name>Collection 1</collection_name>
<title>This is a best novel in the word</title>
<author>Lebowski, Big</author>
<date>2001</date>
</book>
3
<book>
<collection_name>Collection 1</collection_name>
<title>The story of my life</title>
<author>Mouse, Mickey</author>
<date>2012</date>
</book>
4
<book>
<collection_name>Collection 2</collection_name>
<title>Colonize it!</title>
<author>Musk, Elon</author>
<date>2007</date>
</book>
5
<book>
<collection_name>Collection 2</collection_name>
<title>Why I crossed the Rubicon river</title>
<author>Caesar, Julius</author>
<date>2003</date>
</book>
6
<book>
<collection_name>Collection 2</collection_name>
<title>I have no more imagination</title>
<author>Lennon, John</author>
<date>2011</date>
</book>
etc. etc. etc.
所以第二个查询的结果附加到第一个查询的结果。但是有一个问题:order by $date
子句不再起作用了...
我的问题和期望的结果:
至少。如何在每个结果中应用
order by
子句?至少,我想要result from collection 1 ordered by date
+result from collection 2 ordered by date
.充其量。 是否可以将
order by
子句应用于整个结果(即来自 collections 1 的组合结果和2)?充其量,我想要result from collection 1 + result from collection 2 and then order all this by date
)?或者,为此,我必须完全改变我的方法并使用for-each-pair
函数以外的其他东西?在这种情况下,哪个?
期望(最多)结果的示例。
(注意date
和collection_name
)
1
<book>
<collection_name>Collection 1</collection_name>
<title>This is a best novel in the word</title>
<author>Lebowski, Big</author>
<date>2001</date>
</book>
2
<book>
<collection_name>Collection 2</collection_name>
<title>Why I crossed the Rubicon river</title>
<author>Caesar, Julius</author>
<date>2003</date>
</book>
3
<book>
<collection_name>Collection 1</collection_name>
<title>Another greate book</title>
<author>Lincoln, Abraham</author>
<date>2005</date>
</book>
4
<book>
<collection_name>Collection 2</collection_name>
<title>Colonize it!</title>
<author>Musk, Elon</author>
<date>2007</date>
</book>
5
<book>
<collection_name>Collection 2</collection_name>
<title>I have no more imagination</title>
<author>Lennon, John</author>
<date>2011</date>
</book>
6
<book>
<collection_name>Collection 1</collection_name>
<title>The story of my life</title>
<author>Mouse, Mickey</author>
<date>2012</date>
</book>
etc. etc. etc.
非常感谢您的帮助!
编辑 1:
我以 order by date
为例。在实际代码中,我必须能够按 order by title
、order by author
等不同元素(由用户选择)进行排序(但我不需要应用许多不同的 orders by
同时。)所以,也许解决方案应该更“通用”,而不是特别依赖于 order by date
?
当每个项目遍历两个序列时,该函数将应用于每个项目。我认为您需要对 for-each-pair()
的前两个参数中发送的项目集合进行排序,而不是尝试执行一种排序,当它应用第三个参数的函数时,每个项目将是一个项目。
例如,使用一个函数,在该函数中您提供馆藏的名称来获取过滤后的书籍集,并按日期对两个馆藏进行排序作为前两个参数,然后第三个参数的函数简单地将项目和 returns 作为一个序列:
declare function local:sortByDate($path_to_collection) {
for $book in collection($path_to_collection)
let $collection_name := data($book//name_of_collection)
let $title := data($book//title)
let $author := data($book//author)
let $date := data($book//date_of_publication)
where $date >= '2000'
order by $date
return $book
};
for-each-pair(
local:sortByDate("path_to_collection_1"),
local:sortByDate("path_to_collection_2"),
function($collection1, $collection2) {
$collection1, $collection2
}
)
其实很简单。只需要将 for-each-pair
的组合结果作为序列放入变量中。然后循环遍历此序列的所有项目并根据需要对它们进行排序。瞧!
有这种方法的简单架构:
let $results_not_sorted := (
for-each-pair (
collection("path_to_collection_1"),
collection("path_to_collection_2"),
function($collection1, $collection2) {
for $book in $collection1
... etc. (see above the whole query for 'collection 1')
,
for $book in $collection2
... etc. (see above the whole query for 'collection 2')
}
)
)
for $result in $results_not_sorted
order by $result//date (:sort here by whatever you want)
return
$result
和详细代码:
let $results_not_sorted := (
for-each-pair (
collection("path_to_collection_1"),
collection("path_to_collection_2"),
function($collection1, $collection2) {
for $book in $collection1
let $collection_name := data($book/collection)
let $title := data($book/title)
let $author := data($book/author)
let $date := data($book/date)
where $date >= '2000'
return
<book>
<collection_name>{$collection_name}</collection_name>
<title>{$title}</title>
<author>{$author}</author>
<date>{$date}</date>
</book>
,
for $book in $collection2
let $collection_name := data($book//name_of_collection)
let $title := data($book//title)
let $author := data($book//author)
let $date := data($book//date_of_publication)
where $date >= '2000'
return
<book>
<collection_name>{$collection_name}</collection_name>
<title>{$title}</title>
<author>{$author}</author>
<date>{$date}</date>
</book>
}
)
)
for $result in $results_not_sorted
order by $result//date (:sort here by whatever you want)
return
$result