XQuery fn:deep equal-将XPath中的文本与字符串文本进行比较

XQuery fn:deep equal-将XPath中的文本与字符串文本进行比较,xquery,saxon,Xquery,Saxon,我试图使用XQuery函数fn:deep equal来比较XML文档的各个部分,但我得到了意想不到的行为。当比较XPath值和字符串文字时,函数返回false 例如,下面的代码 let $doc := <root> <child><message>Hello</message></child> </root> let $message := <message>Hello</message&

我试图使用XQuery函数fn:deep equal来比较XML文档的各个部分,但我得到了意想不到的行为。当比较XPath值和字符串文字时,函数返回false

例如,下面的代码

let $doc :=
  <root>
    <child><message>Hello</message></child>
  </root>

let $message := <message>Hello</message>

let $value := $doc/child/message/text()
let $compareDirectly := fn:deep-equal($value, "Hello") (: -> false :)
let $compareAsString := fn:deep-equal(fn:concat($value, ""), "Hello") (: -> true :)
let $comparePath := fn:deep-equal($value, $message/text()) (: -> true :)

return
  <results>
    <value>{$value}</value>
    <directly>{$compareDirectly}</directly>
    <asString>{$compareAsString}</asString>
    <path>{$comparePath}</path>
  </results>
let$doc:=
你好
让$message:=你好
let$value:=$doc/child/message/text()
让$compareDirectly:=fn:deep等于($value,“Hello”)(:->false:)
让$compareAsString:=fn:deep相等(fn:concat($value,“”),“Hello”)(:->true:)
让$comparePath:=fn:deep等于($value,$message/text())(:->true:)
返回
{$value}
{$compareDirectly}
{$compareAsString}
{$comparePath}
使用Saxon执行,XQuery程序生成以下XML

<?xml version="1.0" encoding="UTF-8"?>
<results>
    <value>Hello</value>
    <directly>false</directly>
    <asString>true</asString>
    <path>true</path>
</results>

你好
假的
真的
真的
我希望$compareditly是正确的(与其他两个示例相同),但是fn:deep equal似乎并不像我直观地期望的那样工作。我想知道这是否是正确的行为

有没有更好的方法来比较两个XML节点

我正在寻找一些通用的解决方案,它既可以用于XML代码段(例如示例中的$doc或$message值),也可以用于字符串文本的这种特殊情况。

来源:

要实现深度相等,它们必须包含成对深度相等的项;要使两个项深度相等,它们必须要么是比较相等的原子值,要么是具有相同名称的同类节点,其子项深度相等

这就是为什么在比较文本节点和原子类型时它不会返回true。在另外两个示例中,比较了两种字符串原子类型。看起来好像不需要deepequal,它递归地比较节点。如果是这种情况,那么您可以只比较字符串:

$doc/child/message/string() eq $message/string()
=> true()

如果还有其他要求,那么您可能需要更新示例以更清楚地演示这些要求。

我正在尝试编写一个通用函数,该函数与示例中XML文档中的节点(如$doc或$message的值)进行比较,效果很好。我对fn的问题:deep equal($value,“Hello”)在某种程度上是一个特例,但我也需要讨论这个问题。我不想添加比较节点的示例,因为它按预期工作,并且我试图保持示例的简单性,但仍然是可执行的。这不是一个特例,因为您正在执行的是相当于
deep equal(text{“Hello”},“Hello”)
,它将文本节点与字符串原子类型进行比较。由于这些是不同类型的数据,因此“深度相等”是错误的。这有道理吗?是的,你的解释有道理。我的引数有点误导——从我的角度来看,这是一个特例,因为我通常比较节点,而不是原子值,但这只是我使用它的方式。您的示例实际上帮助解决了我的问题,感谢您指出了类型上的差异。最初我尝试使用“…message/text()”。如果我将示例改为使用“message/string()”,代码会达到预期效果。@ArnostValicek对,text()可能很棘手-它选择文本节点序列,这通常不是人们想要的。文本可能看起来是连续的,但实际上由多个文本节点组成。i、 e.:
let$t:=(text{this},text{is some},text{text.})返回计数($t/text())=>3