Самый простой способ сделать это - создать выражение xpath, которое сверяется с узлами критериев. Например:
Шаг 1: Далее будут выбраны все узлы, которые не находятся в области критериев (поэтому все узлы, у которых нет родителя с именем «критерии»)
//*[name(..) != 'criteria']
Шаг 2: Отфильтруйте все узлы, которые также появляются в разделе critera
//*[name(..) != 'criteria' and not(name(//criteria/*) = name(.))]
Теперь последний оператор выберет все узлы, которые не соответствуют узлу критерия. Но вам просто нужны подчиненные узлы, поэтому мы можем изменить селектор так, чтобы он захватывал только те элементы, которые являются «вложенными элементами» или конечными элементами, которые не имеют дочерних узлов.
//*[name(..) != 'criteria' and not(name(//criteria/*) = name(.)) and not(*)]
Итак, вот разбивка каждого из наших условных выражений еще раз:
name (..)! = 'Критерии' - ограничения на узлы, которых нет в разделе критериев
not (имя (// критерии / *) = имя (.)) - ограничения для узлов, которые не имеют того же имени, что и узел в разделе критериев
а не (*) - ограничения на узлы, у которых нет дочерних узлов (так что это конечные узлы, которые вы хотите.)
Так что если бы вы делали что-то вроде:
<xsl:for-each select="//*[name(..) != 'criteria' and not(name(//criteria/*) = name(.)) and not(*)]">
<xsl:value-of select="name(current())"/> :
</xsl:for-each>
В приведенном выше примере это выглядело бы так:
subel1 : subel2
Надеюсь, это поможет.
Приветствия
Casey