Главная » XSLT » Отбор всех элементов, кроме одного

0

Задача

Требуется отобрать все элементы в определенном контексте за исключением некоторых.

Решение

Самый лучший способ отобрать все элементы, кроме одного, такой:

<xsl:apply-templates select="*[not(self::element-to-ignore)]"/>

или то же самое, но посредством итерации:

<xsl:for-each select="*[not(self::element-to-ignore)]">

</xsl:for-each>

Обсуждение

Когда неопытный программист на XSLT в первый раз пытается отобрать все элементы, кроме одного, ему на ум чаще всего приходит такая конструкция:

<xsl:apply-templates select="*[name() != ‘element-to-ignore’]"/>

Во многих случаях такой код будет работать, проблемы возникнут, когда в документе используются пространства имен. Напомню, что функция name() возвращает квалифицированное имя узла (QName), то есть префикс простран­ства имен, конкатенированный с локальной частью имени. Однако никто не зас­тавляет автора XML-документа использовать конкретный префикс.

<!– He 6yneT paбoтaть, ecли aвтop написал SALES:product вместо

sales:product –>

<xsl:apply-templates select="*[name() != ‘sales:product’]"/>

Можно было бы воспользоваться функцией local-name(). Но тогда были бы проигнорированы элементы из всех пространств имен с заданным локальным именем. Вряд ли это то, что вы хотите получить.

Эта рекомендация относится только к элементам, а не к атрибутам. Если нуж­но отобрать все атрибуты, кроме одного, смело используйте local-name(). Если речь идет об именах, то ось self содержит только элементы. Иными словами, пиши­те <xsl:copy-of select=@*[local-name() != ‘ignored-attribute’]/>, а не <xsl:copy-of select = @*[not(self::ignored-attribute)]/>.

Наконец, чтобы избежать путаницы, отметим, что отбор всех элементов, кроме одного, – не то же самое, что отбор всех элементов, кроме одного экземпляра элемента. Вторая задача решается так, как показано в одном из ранее встречавшихся примеров:

<xsl:apply-templates select="*[generate-id() != generate-id($node-to-ignore) ]"/>

См. также

В книге Дженни Теннисон XSLT and XPath on the Edge (M&T Books, 2001) под­робно рассматривается вопрос о том, когда следует и не следует применять функ­ции name() иlocal-name().

Мангано Сэл  XSLT. Сборник рецептов. – М.: ДМК Пресс, СПБ.: БХВ-Петербург, 2008. – 864 с.: ил.

По теме:

  • Комментарии