我有以下两个XML,问题陈述如下。
解析 XML 1,如果任何node_x的子节点的名称中包含"a"(如 value_a_0 中(,并且value_a_0包含特定数字,则解析 XML 2 并转到 node_x-1 中的所有abc_x,并将value_x-1_0/1/2/3的内容与某些实体进行比较。
如果任何node_x的子节点的名称中包含"b"(如value_b_0(,并且value_b_0包含特定的数字(例如"m"(,则解析XML 2并转到node_x+1的所有abc_x,并将value_x-1_0/1/2/3的内容与"m"进行比较。
示例:对于record1中的所有value_a_0,检查value_a_0节点是否包含 5。如果是这样,node_1和node_9属于这种情况,请转到record2/node_0和record2/node_8并比较 value_0_0/1/2/3 的内容,无论它们是否包含 5。同样,对于其余情况。
我想知道解决它的最佳实践是什么?Xpath 3.0 中是否有任何哈希表方法?
第一个 XML
<record1>
<node_1>
<value_a_0>5</value_1_0>
<value_b_1>0</value_1_1>
<value_c_2>10</value_1_2>
<value_d_3>8</value_1_3>
</node_1>
.................................
.................................
<node_9>
<value_a_0>5</value_a_0>
<value_b_1>99</value_b_1>
<value_c_2>53</value_c_2>
<value_d_3>5</value_d_3>
</node_9>
</record1>
第二个 XML
<record2>
<abc_0>
<node_0>
<value_0_0>5</value_0_0>
<value_0_1>0</value_0_1>
<value_0_2>150</value_0_2>
<value_0_3>81</value_0_3>
</node_0>
<node_1>
<value_1_0>55</value_1_0>
<value_1_1>30</value_1_1>
<value_1_2>150</value_1_2>
<value_1_3>81</value_1_3>
</node_1>
.................................
.................................
<node_63>
<value_63_0>1</value_63_0>
<value_63_1>99</value_63_1>
<value_63_2>53</value_63_2>
<value_63_3>5</value_63_3>
</node_63>
</abc_0>
================================================
<abc_99>
<node_0>
<value_0_0>555</value_0_0>
<value_0_1>1810</value_0_1>
<value_0_2>140</value_0_2>
<value_0_3>80</value_0_3>
</node_0>
<node_1>
<value_1_0>555</value_1_0>
<value_1_1>1810</value_1_1>
<value_1_2>140</value_1_2>
<value_1_3>80</value_1_3>
</node_1>
<node_2>
<value_2_0>5</value_2_0>
<value_2_1>60</value_2_1>
<value_2_2>10</value_2_2>
<value_2_3>83</value_2_3>
</node_2>
.................................
.................................
<node_63>
<value_63_0>1</value_63_0>
<value_63_1>49</value_63_1>
<value_63_2>23</value_63_2>
<value_63_3>35</value_63_3>
</node_63>
</abc_99>
</record2>
首先,我想说使用这样的结构化元素名称是非常糟糕的XML设计。这是相关的,因为当您在 XPath 或 XQuery 中执行连接查询时,您非常依赖优化器来查找快速执行路径(例如哈希连接(,并且查询越"奇怪",优化器就越不可能找到快速执行策略。
我经常从将"奇怪的"XML转换为更卫生的东西开始。例如,在这种情况下,我会将<value_a_0>5</value_1_0>
转换为<value cat="a" seq="0">5</value>
。这样可以更轻松地编写查询,并使优化程序更容易识别它,并且转换阶段是可重用的,因此您可以在对 XML 执行任何操作之前应用它,而不仅仅是此操作。
如果要在联接查询上寻找优于 O(n*m( 的性能,则需要查看所选 XPath 引擎的功能。例如,Saxon-EE会做这样的优化,Saxon-HE不会。您通常更有可能在 XQuery 引擎中找到高级优化,而不是 XPath 引擎。
至于您查询的细节,当您开始谈论abc_x
时,我对要求语句迷失了方向。我不确定这指的是什么。
这似乎是一个可以通过分组部分解决的任务,但与前面的示例一样,XML 元素名称的不当使用都因索引值而异,索引值应该是元素或属性值的一部分,而不是元素名称的一部分,这使得编写简洁的代码变得更加困难:
let $abc-elements := $doc2/record2/*
for $node-element in record1/*
for $index in (1 to count($node-element[1]/*))
for $index-element in $node-element/*[position() = $index]
group by $index, $group-value := $index-element
where tail($index-element)
return
<group index="{$index}" value="{$group-value}">
{
let $suffixes := $index-element/../string((xs:integer(substring-after(local-name(), '_')) - 1)),
$relevant-abc-node-elements := $abc-elements/*[substring-after(local-name(), '_') = $suffixes]
return $relevant-abc-node-elements[* = $group-value]
}
</group>
https://xqueryfiddle.liberty-development.net/nbUY4kA