Синтаксис XSLT & Xpath> как обращаться к элементу во «внешней» области видимости - PullRequest
1 голос
/ 04 декабря 2009

У меня следующее работает на 100% правильно. Однако, чтобы удовлетворить мое любопытство ... есть ли способ достичь того же самого, не объявляя переменную currentID? Есть ли способ сослаться на него из условия «теста» Xpath?

Запрос xpath в условии должен ссылаться на 2 атрибута @id, чтобы увидеть, совпадают ли они.

  • текущая @id
  • каждый «предок» @ id

Вот код:

<xsl:variable name="currentID" select="@id" />
<xsl:attribute name="class">
<xsl:if test="count($currentPage/ancestor::node [@id = $currentID])&gt;0">descendant-selected </xsl:if>
</xsl:attribute>

Ответы [ 5 ]

3 голосов
/ 04 декабря 2009

Поскольку вы выбираете $currentID из узла контекста:

<xsl:variable name="currentID" select="@id" />

вы можете использовать функцию current(), которая всегда ссылается на узел контекста XSLT:

<xsl:attribute name="class">
  <xsl:if test="count($currentPage/ancestor::node[@id = current()/@id) &gt; 0]">
    <xsl:text>descendant-selected </xsl:text>
  </xsl:if>
</xsl:attribute>

Таким образом, вам не нужна переменная.

Несколько других заметок:

  • Я рекомендую использовать <xsl:text>, как показано выше. Это дает вам больше свободы для форматирования кода и позволяет избежать чрезмерно длинных строк.
  • Вам не нужно делать count() > 0, достаточно просто выбрать узлы. Если ничего не существует, возвращается пустой набор узлов. Он всегда оценивается как false, а непустые наборы узлов всегда оцениваются как true.

Если вы регулярно ссылаетесь на узлы @id в своей таблице стилей XSL, <xsl:key> станет полезным:

<xsl:key name="kNodeById" match="node" use="@id" />

<!-- ... -->

<xsl:attribute name="class">
  <xsl:if test="key('kNodeById', @id)">
    <xsl:text>descendant-selected </xsl:text>
  </xsl:if>
</xsl:attribute>

Выше не требуется current(), поскольку вне предиката XPath контекст не изменяется. Кроме того, я не count() узлов, так как это избыточно (как объяснено).

2 голосов
/ 04 декабря 2009

Используйте current () для ссылки на текущий узел, обработанный шаблоном:

<xsl:if test="count($currentPage/ancestor::node [@id = current()/@id])&gt;0">
1 голос
/ 08 декабря 2009

Как уже выяснилось, ссылка на «внешнюю область» не была проблемой, так как вы могли сделать прямое сравнение, используя оператор «=». Тем не менее, есть некоторые случаи, когда вам нужен current (), и даже больше, кроме случаев, когда даже current () не обрезает его (потому что вам нужно «объединиться» между несколькими контекстами). В этих случаях выражения «for» в XPath 2.0 необходимы.

1 голос
/ 04 декабря 2009

Тим заставил меня задуматься .... Я думаю, что я слишком усложнил вещи, и я попробовал следующее, что работает.

<xsl:if test="@id = $currentPage/ancestor::node/@id">descendant-selected </xsl:if>

XSLT выглядит счастливым, сравнивая атрибут с набором атрибутов и оценивая значение true, если какой-либо из них совпадает? если у кого-то есть лучшее объяснение того, почему это работает или что-то лучше (более лаконичное), тогда опустите его.

0 голосов
/ 04 декабря 2009

Вы можете просто сделать:

<xsl:if test="count($currentPage[ancestor::node/@id = @id])&gt;0">descendant-selected </xsl:if>
...