#xpath #xslt-2.0
#xpath #xslt-2.0
Вопрос:
Пример:
<ul>
<li>item 1</li>
<ul>
<li>item 2</li>
<li>item 3</li>
<ul>
<li>item 5</li> <!-- context node -->
</ul>
</ul>
<li>item 6</li>
</ul>
Если li
элемент с текстом item 5
является контекстным узлом, выражение following::*
выдаст li
элемент с текстом item 6
. Есть ли встроенный способ получить разницу в глубине этих узлов? т.е. если мы определили корень ul
как имеющий глубину 0, то его дочерние элементы ( li
пункт 1, ul
, li
пункт 6) будут иметь глубину 1 и так далее. li
элемент 5 имеет глубину 3.
ancestor
Ось может использоваться из обоих узлов, но интересно, есть ли другой способ. Другой возможностью может быть сохранение информации о состоянии при обходе дерева и если у родителя были следующие братья и сестры?
Комментарии:
1. Что не работает с использованием (количество?)
ancestor
оси? Что касается сохранения информации о состоянии при обходе дерева, в XSLT 3 вы могли бы сделать это с помощью аккумуляторов.2. @MartinHonnen
ancestor
ось будет работать, мне было любопытно, есть ли более элегантное решение. Накопитель — хорошая функция для XSLT 3.
Ответ №1:
Вопрос помечен как XSLT 2, но, как вы упомянули обход дерева для сохранения информации о состоянии, возможно, стоит упомянуть накопитель XSLT 3, например
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode use-accumulators="depth"/>
<xsl:accumulator name="depth" as="xs:integer" initial-value="0">
<xsl:accumulator-rule match="/" select="0"/>
<xsl:accumulator-rule match="*" select="$value 1"/>
<xsl:accumulator-rule match="*" phase="end" select="$value - 1"/>
</xsl:accumulator>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="*">
<xsl:comment select="accumulator-before('depth'), count(ancestor-or-self::*)"/>
<xsl:next-match/>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle .liberty-development.net/ei5R4uS
Я знаю, что вы определили значение для корневого элемента как 0, но использование 0 для корневого узла /
, а затем 1
в качестве глубины для его дочерних элементов кажется мне более разумным.