Выберите дочерние узлы на основе их содержимого
Вопрос
Фрагмент 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>
Решение
Одним из простейших решений вопроса OP является следующее выражение 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']