Выберите дочерние узлы на основе их содержимого - PullRequest
13 голосов
/ 05 апреля 2009

Фрагмент XML:

<AA>
  <BB>foo</BB>
  <CC>bar</CC>
  <DD>baz</DD>
  <EE>bar</EE>
</AA>

Как выбрать все дочерние узлы <AA>, которые имеют bar в качестве содержимого? В приведенном выше примере я бы хотел выбрать <CC> и <EE>. Я думаю, что решение что-то вроде:

<xsl:template match="AA">
  <xsl:for-each select="???" />
</xsl:template>

1 Ответ

27 голосов
/ 05 апреля 2009

Одним из самых простых решений вопроса ОП является следующее выражение XPath :

*/*[.='bar']

Обратите внимание, что инструкция XSLT не используется - это просто выражение XPath , поэтому вопрос может быть помечен только как XPath.

С этого момента можно использовать это выражение XPath в XSLT различными способами, например применять шаблоны ко всем выбранным узлам .

Например, ниже приведено XSLT-преобразование, которое принимает XML-документ и создает другой, в котором удаляются все элементы - дочерние элементы <AA>, содержимое которых не равно "bar":

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:template match="node()|@*">
      <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="AA">
      <xsl:copy>
         <xsl:apply-templates select="*[. = 'bar']"/>
      </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к исходному документу XML :

<AA>
    <BB>foo</BB>
    <CC>bar</CC>
    <DD>baz</DD>
    <EE>bar</EE>
</AA>

желаемый результат получается :

<AA>
   <CC>bar</CC>
   <EE>bar</EE>
</AA>

Примечание :

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

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