2016-12-02 7 views
0

Моего XML источника данных:выберите узлы с совпадающим, но неизвестными значениями в дочерних узлы

<impact_categories> 
    <impact_category> 
     <name>Cat1</name> 
     <impact_levels> 
      <impact_level> 
       <name>Insignificant</name> 
      </impact_level> 
     </impact_levels> 
    </impact_category> 
    <impact_category> 
     <name>Cat2</name> 
     <impact_levels> 
      <impact_level> 
       <name>Lowest</name> 
      </impact_level> 
     </impact_levels> 
    </impact_category> 
    <impact_category> 
     <name>Cat3</name> 
     <impact_levels> 
      <impact_level> 
       <name>Insignificant</name> 
      </impact_level> 
     </impact_levels> 
    </impact_category> 
</impact_categories> 

Мне нужно, чтобы выбрать все impact_category узлов, которые имеют идентичный набор impact_level детей. В этом примере я хочу выбрать Cat1 и Cat 3, потому что их дочерние значения являются «Незначительными». Сделав некоторые вещи с этими узлами, мне нужно выбрать следующую партию узлов impact_category, у которых есть другой набор подходящих дочерних элементов impact_level (в этом примере Cat2, значение которого является «самым низким») и т. Д.

Моя проблема заключается в том, что я не буду знать, какие значения будут до времени выполнения, и они могут отличаться для разных пользователей. Я относительный новичок XPath, поэтому не знаю, как это сделать. Я потратил часы на поиск в Интернете и в книгах, но все примеры, которые я нашел, предполагают, что вы сопоставляетесь с известными значениями. Извиняюсь, если это что-то действительно простое, но я действительно застрял.

+0

Очень «твердый орех» (как мы говорим на немецком языке) для новичка. Посмотрите на [muenchian grouping] (http://stackoverflow.com/search?q=muenchian+grouping) –

+0

Но как вы хотите выбрать конкретные категории воздействия для дальнейшей обработки, если вы не знаете возможных значений уровней воздействия авансовые? – Markus

ответ

0

Существует функция deep-equal, которая позволяет сравнивать поддерева, так что вы можете, например, выбрать

let $cat := /impact_categories/impact_category 
return $cat[some $cat2 in ($cat except .) satisfies deep-equal(impact_levels, $cat2/impact_levels)] 

impact_category вернуть элементы с impact_levels глубоко равным ребенком к другим impact_category s impact_levels.

В XSLT 2.0 вы также можете сгруппировать <xsl:for-each-group select="/impact_categories/impact_category" group-by="impact_levels/impact_level/name">, если вы знаете, что существует только один такой потомок, вы можете легко группировать элементы таким образом, если вам несколько может потребоваться вычислить отпечаток пальца или использовать XSLT 3.0 и композитный ключи.