Вопрос:

Более быстрые выражения XPath для выполнения запросов из нескольких XML

xpath xquery xpath-2.0 xpath-3.0

12 просмотра

2 ответа

125 Репутация автора

У меня есть два следующих XML-файла, и постановка проблемы заключается в следующем.

  1. Выполните синтаксический анализ 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 с определенными лицами.

  2. Если подузел любого node_x содержит в своем имени «b» (как в value_b_0 ), а value_b_0 содержит конкретное число (скажем, «m»), проанализируйте XML 2 и перейдите к node_x + 1 для всех abc_x в и сравните содержимое value_x- 1_0 / 1/2/3 с «м».

Пример: для всех значений value_a_0 в записи1 проверьте, содержит ли узел 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>
Автор: beginner Источник Размещён: 11.08.2019 03:28

Ответы (2)


0 плюса

116073 Репутация автора

Во-первых, я бы сказал, что использование таких структурированных имен элементов - это довольно плохой дизайн 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. Я не уверен, к чему это относится.

Автор: Michael Kay Размещён: 11.08.2019 07:35

0 плюса

116797 Репутация автора

Это похоже на задачу, которая может быть частично решена путем группировки, но, как и в ваших предыдущих примерах, плохое использование имен элементов 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

Автор: Martin Honnen Размещён: 11.08.2019 09:42
Вопросы из категории :
32x32