我正在尝试使用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>
使用Saxon执行,XQuery程序生成以下XML
<?xml version="1.0" encoding="UTF-8"?>
<results>
<value>Hello</value>
<directly>false</directly>
<asString>true</asString>
<path>true</path>
</results>
我希望$ compareDirectly是真的(和其他两个例子一样),但是fn:deep-equal似乎不像我直觉所期望的那样工作。我想知道这是否是正确的行为。
有没有更好的哇如何比较两个XML节点?
我希望找到一些可用于两个XML片段的通用解决方案(例如$ doc或$ message的值)以及字符串文字的特殊情况。
答案 0 :(得分:2)
来自the spec:
要深度相等,它们必须包含成对深度相等的项目;并且对于两个深度相等的项,它们必须是比较相等的原子值,或同一类型的节点,具有相同的名称,其子项是深度相等的。
因此,在将文本节点与原子类型进行比较时,它不会返回true。在另外两个示例中,您将比较两个字符串原子类型。看起来好像你不需要深度相等,它递归地比较节点。如果是这种情况,那么你可以只比较字符串:
$doc/child/message/string() eq $message/string()
=> true()
如果还有其他要求,那么您可能需要更新您的示例以更清楚地演示这些要求。