XSL (T) текущий / предыдущий / следующий - PullRequest
2 голосов
/ 15 июля 2009

Я знаю, что есть функция current() для извлечения текущего узла в XSL, но есть ли возможность ссылаться на "предыдущий" и "следующий" узлы в отношении текущей позиции?

Ответы [ 3 ]

4 голосов
/ 15 июля 2009

Нет. Текущий контекст не может знать, какие узлы являются «следующими» или «предыдущими».

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

  1. Вы делаете: <xsl:apply-templates select="*" /><!-- select 3 nodes (a,b,c) -->
  2. Процессор XSLT составляет список узлов для обработки (a, b, c)
  3. Для каждого из этих узлов процессор XSLT выбирает и выполняет соответствующий шаблон
  4. Когда вызывается шаблон, определяется узел current() и определяется position(), но кроме этого шаблон не знает о потоке выполнения.
  5. Порядок выполнения зависит от предпочтений процессоров, если результат гарантированно будет одинаковым. Ваши (теоретические) прогнозы могут быть верны для одного процессора и неверны для другого. Я думаю, что для языка программирования без побочных эффектов, такого как XSLT, такие знания были бы опасны (потому что люди начали бы полагаться на порядок выполнения).

Вы можете использовать оси following::sibling или preceding::sibling XPath, но это не то же самое, что знать, какой узел будет обрабатываться следующим

EDIT

Приведенное выше объяснение пытается ответить на вопрос так, как он был задан, но ОП означало нечто иное. Речь идет о группировании / выводе только уникальных узлов.

В соответствии с запросом OP, здесь быстрая демонстрация того, как добиться группировки с использованием осей XPath.

XML (элементы предварительно отсортированы):

<items>
  <item type="a"></item>
  <item type="a"></item>
  <item type="a"></item>
  <item type="a"></item>
  <item type="b"></item>
  <item type="e"></item>
</items>

1035 * XSLT *

<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>

  <xsl:template match="/items">
    <!-- copy the root element -->
    <xsl:copy>
      <!-- select those items that differ from any of their predecessors -->
      <xsl:apply-templates select="
        item[
          not(@type = preceding-sibling::item/@type)
        ]
      " />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="item">
    <!-- copy the item to the output -->
    <xsl:copy-of select="." />
  </xsl:template>

</xsl:stylesheet>

Выход:

<items>
  <item type="a"></item>
  <item type="b"></item>
  <item type="e"></item>
</items>
1 голос
/ 15 июля 2009

Если вы говорите о следующих и предыдущих узлах в структуре документа, в отличие от текущего потока выполнения (например, цикла for-each), см. Оси preceding-sibling и following-sibling: Оси XPath на W3 .

Чтобы получить следующий узел с тем же именем:

following-sibling::*[name() = name(current())]

В зависимости от контекста вам может понадобиться использовать name(.) в первой части.

0 голосов
/ 15 июля 2009

Вы можете отслеживать предыдущие и текущие переменные для последующей обработки. То есть Вы можете сохранить тег (i-2), тег (i-1) и работать с ними в теге (i).

Просто еще одна идея.

Привет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...