我有以下两种XML,问题说明如下。
解析XML 1,并且如果任何 node_x 的子节点的名称中包含“ a”(如 value_a_0 )和 value_a_0 包含一个特定数字,解析XML 2并转到所有 abc_x 的 node_x-1 ,并比较 value_x-1_0 / 1/2/3 < / strong>和某些实体。
如果任何 node_x 的子节点名称中包含“ b”(例如 value_b_0 ),并且 value_b_0 中包含特定数字(例如'm'),解析XML 2并转到其中的所有 abc_x 的 node_x + 1 并比较 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>
答案 0 :(得分:4)
首先,我想说使用这样的结构化元素名称是非常糟糕的XML设计。这是相关的,因为当您在XPath或XQuery中执行联接查询时,您非常依赖优化器来查找快速执行路径(例如,哈希联接),并且查询“更奇怪”时,优化器执行的可能性越小找到快速执行策略。
我通常首先将“怪异”的XML转换为更卫生的东西。例如,在这种情况下,我会将<value_a_0>5</value_1_0>
转换为<value cat="a" seq="0">5</value>
。这样可以更轻松地编写查询,并使优化程序更易于识别查询,并且转换阶段是可重用的,因此您可以在对XML进行任何操作之前而不只是对XML进行操作。
如果要在联接查询上寻求优于O(n * m)的性能,则需要查看所选XPath引擎的功能。例如,Saxon-EE将进行此类优化,而Saxon-HE则不会。通常,您比XPath引擎更可能在XQuery引擎中找到高级优化。
关于查询的详细信息,当您开始谈论abc_x
时,我对需求陈述感到迷惑。我不确定这是指什么。
答案 1 :(得分:2)
这似乎可以通过分组来部分解决,但正如您在前面的示例中一样,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>