. = preceding::*
- истина, если значение текущего узла равно значению некоторого предыдущего узла. Здесь необходимо понять четыре концепции, и я не уверен, с какой из них у вас возникли трудности:
.
означает текущий узел. Вам абсолютно необходимо понять эту концепцию, чтобы вообще понять XPath
=
в XPath немного необычно: он проверяет, равен ли какой-либо из элементов на lhs любой из элементов в правой части, по сути, X = Y
означает, что «некоторый элемент в X равен некоторому элементу в Y`.
preceding::*
выбирает все элементы, предшествующие текущему элементу в том же документе, в порядке документа. В действительности, если заданы два элемента A и B, A предшествует B, если тег A end появляется в документе раньше, чем тег B start .
строковое значение: если к узлам применяется операция типа "=", она фактически работает со строковыми значениями узлов. Для простого элемента, такого как <x>23</x>
, строковое значение элемент равен 23.
Итак
not(. = preceding::*)
проверяет, отличается ли элемент от всех предыдущих элементов
и
//*[not(. = preceding::*)]
поэтому выбирает все элементы, которые не являются дубликатами.
Like большинство хитростей в XSLT 1.0, конечно же, становится намного проще с XSLT 2.0 - и даже если у вас есть несчастье застрять в XSLT 1.0, есть более эффективные способы решения проблем группировки с помощью ключей.