如何在select element type xquery上深入比较节点,搜索具有匹配子元素的节点?
假设我有两个xml文档 xml1 这是我到目前为止尝试的,但是如果我理解正确,这应该只检查第一层 编辑:为了以防万一,对搜索规则进行更好的规范:“b”节点是一个结果节点,当且仅当它包含xml1中指定的所有且仅包含“a”节点时,而两个“a”节点是相同的,如果它们具有相同的名称和相同的“a”节点子节点 编辑2: 为了澄清,以下两个“b”相等如何在select element type xquery上深入比较节点,搜索具有匹配子元素的节点?,xquery,Xquery,假设我有两个xml文档 xml1 这是我到目前为止尝试的,但是如果我理解正确,这应该只检查第一层 编辑:为了以防万一,对搜索规则进行更好的规范:“b”节点是一个结果节点,当且仅当它包含xml1中指定的所有且仅包含“a”节点时,而两个“a”节点是相同的,如果它们具有相同的名称和相同的“a”节点子节点 编辑2: 为了澄清,以下两个“b”相等 <r> <b id="1"> <a name="1"> <a name
<r>
<b id="1">
<a name="1">
<a name="2"/>
</a>
</b>
</r>
及
以下解决方案假设每个级别上可能有多个
a
元素,并且假设这些元素的顺序必须相同:
declare variable $xml1 := <req>...</req>;
declare variable $xml2 := <r>...</r>;
declare function local:deep-equal-a($xml, $find) {
let $xas := $xml/a, $fas := $find/a
return count($xas) = count($fas) and (
every $test in for-each-pair($xas, $fas, function($xa, $fa) {
$xa/@name = $fa/@name and local:deep-equal-a($xa, $fa)
}) satisfies $test
)
};
for $b in $xml2/b
where local:deep-equal-a($b, $xml1)
return $b
如果您不一定要找到递归解决方案,那么您可能需要看看fn:deep equal。我更正了它。解决方案不必是递归的,我只是不知道如何描述它。但是我只需要它们在“a”类型的元素上相等,它们可以有任何其他不相同的子元素,只要“a”元素匹配即可。我不能使用内联函数(不受支持),所以我将其修改为
declare function local:cmp pair($xa,$fa){return$xa/@name=$fa/@name和local:deep-equal-a($xa,$fa)}代码>但是,这给了我一个错误“XPST0003:expected”},发现“$”您是否选择了解决方案1或解决方案2?您的意思是不支持每对解决方案?您使用的是哪个XQuery处理器?我使用了第一个示例。查询处理器是Saxon,它在高阶函数上抛出错误。尝试用(对于要计数的$c in 1($xas),让$xa:=$xas[$c]让$fa:=$fas[$c]返回$xa/@name=$fa/@name和local:deep-equal-a($xa,$fa))
for $r in $xml2/r/b
where (every $a
in $r/a
satisfies $a/@name = $xml1/req/a/@name)
return $r
<r>
<b id="1">
<a name="1">
<a name="2"/>
</a>
</b>
</r>
<r>
<b id="1">
<a name="1">
<a name="2"/>
<d/>
</a>
<c/>
</b>
</r>
declare variable $xml1 := <req>...</req>;
declare variable $xml2 := <r>...</r>;
declare function local:deep-equal-a($xml, $find) {
let $xas := $xml/a, $fas := $find/a
return count($xas) = count($fas) and (
every $test in for-each-pair($xas, $fas, function($xa, $fa) {
$xa/@name = $fa/@name and local:deep-equal-a($xa, $fa)
}) satisfies $test
)
};
for $b in $xml2/b
where local:deep-equal-a($b, $xml1)
return $b
declare function local:deep-equal-a($xml, $find) {
let $xa := $xml/a, $fa := $find/a
return not($xa and $fa) or
$xa/@name = $fa/@name and local:deep-equal-a($xa, $fa)
};