具有递归定义的 XPath
XPath with recursive definitions
我有这样的 DTD:
<!ELEMENT Root (Thread*) >
<!ELEMENT Thread(ThreadId, Message) >
<!ELEMENT Replies(message+) >
<!ELEMENT message(timestamp, sender, recipient, subject, text, Replies?)>
所以一个线程会有一个消息,这个消息可以有一个节点'replies',然后这个节点可以包含消息等等,直到结构的底部。
现在我要做的是先检索消息最多的线程的 ID,然后检索嵌套回复链最长的线程的 ID。
这感觉像是一个递归问题,但我无法在 XPath 中处理它。到目前为止,我尝试过这样的事情:
For $thread in //thread
Count(descendant-or-self::$thread/message)
对于每个线程,我尝试计算子消息节点的数量,但此解决方案计算线程的所有子节点的数量,因此包括回复节点。
我对这类问题感到迷茫,因为我不知道在这些问题中该做什么 'recursive situations'。
假设您可以使用 XPath 3.0,例如
let $max := max(/Root/Thread/count(.//Message))
return /Root/Thread[count(.//Message) eq $max]/ThreadId
查找消息最多的线程的 ID,我认为
let $max := max(/Root/Thread/Message//Replies[not(Message/Replies)]/count(ancestor::Replies))
return /Root/Thread[Message//Replies[not(Message/Replies)]/count(ancestor::Replies) = $max]/ThreadId
查找具有最长嵌套回复链的线程的 ID。
对于 XPath 2.0,您没有 let
表达式,因此您必须将示例中绑定的代码内联到引用变量的位置。
在 XPath 3.1 中,您有一个 sort
函数 (https://www.w3.org/TR/xpath-functions-31/#func-sort),因此无需计算最大值并选择具有最大值的项目,您可以排序并取最后一个,例如
sort(/Root/Thread, (), function($t) { max($t/Message//Replies[not(Message/Replies)]/count(ancestor::Replies)) })[last()]/ThreadId
对于第二个更复杂的查询或
sort(/Root/Thread, (), function($t) { count($t//Message) })[last()]/ThreadId
第一个。
我有这样的 DTD:
<!ELEMENT Root (Thread*) >
<!ELEMENT Thread(ThreadId, Message) >
<!ELEMENT Replies(message+) >
<!ELEMENT message(timestamp, sender, recipient, subject, text, Replies?)>
所以一个线程会有一个消息,这个消息可以有一个节点'replies',然后这个节点可以包含消息等等,直到结构的底部。
现在我要做的是先检索消息最多的线程的 ID,然后检索嵌套回复链最长的线程的 ID。
这感觉像是一个递归问题,但我无法在 XPath 中处理它。到目前为止,我尝试过这样的事情:
For $thread in //thread
Count(descendant-or-self::$thread/message)
对于每个线程,我尝试计算子消息节点的数量,但此解决方案计算线程的所有子节点的数量,因此包括回复节点。
我对这类问题感到迷茫,因为我不知道在这些问题中该做什么 'recursive situations'。
假设您可以使用 XPath 3.0,例如
let $max := max(/Root/Thread/count(.//Message))
return /Root/Thread[count(.//Message) eq $max]/ThreadId
查找消息最多的线程的 ID,我认为
let $max := max(/Root/Thread/Message//Replies[not(Message/Replies)]/count(ancestor::Replies))
return /Root/Thread[Message//Replies[not(Message/Replies)]/count(ancestor::Replies) = $max]/ThreadId
查找具有最长嵌套回复链的线程的 ID。
对于 XPath 2.0,您没有 let
表达式,因此您必须将示例中绑定的代码内联到引用变量的位置。
在 XPath 3.1 中,您有一个 sort
函数 (https://www.w3.org/TR/xpath-functions-31/#func-sort),因此无需计算最大值并选择具有最大值的项目,您可以排序并取最后一个,例如
sort(/Root/Thread, (), function($t) { max($t/Message//Replies[not(Message/Replies)]/count(ancestor::Replies)) })[last()]/ThreadId
对于第二个更复杂的查询或
sort(/Root/Thread, (), function($t) { count($t//Message) })[last()]/ThreadId
第一个。