Применение:
//dt[. = 'cat1']
/following-sibling::dd
[count(.| //dt[. = 'cat2']/preceding-sibling::dd)
=
count(//dt[. = 'cat2']/preceding-sibling::dd)
]
При условии, что //dt[. = 'cat1']
и //dt[. = 'cat2']
каждый выбор оны одного элемента, приведенное выше выражение выбирает именно те хотело два dd
элементов.
XSLT - на основе проверки:
<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="/">
<xsl:copy-of select=
"//dt[. = 'cat1']
/following-sibling::dd
[count(.| //dt[. = 'cat2']/preceding-sibling::dd)
=
count(//dt[. = 'cat2']/preceding-sibling::dd)
]
"/>
</xsl:template>
</xsl:stylesheet>
Когда это преобразование применяется на прилагаемом документе XML (со значениями последних двух dd
с измененными, поэтому мы знаем наверняка, что хотел элементы выбраны):
выражение
<dl class="ismSummary ismHomeSummary">
<dt>cat1</dt>
<dd>value1</dd>
<dd>value2</dd>
<dt>cat2</dt>
<dd>value3</dd>
<dd>value4</dd>
</dl>
XPath вычисляется и п оды он выбирает копируются на выход:
<dd>value1</dd>
<dd>value2</dd>
Объяснение:
Здесь мы используем метод Kayessian для пересечения множество узлов в XPath 1.0:
Пересечение двух множеств узлов: $ns1
и $ns2
является:
$ns1[count(.|$ns2) = count($ns2)]
В нашем случае мы заменим $ns1
с:
//dt[. = 'cat1']/following-sibling::dd
и подставим $ns2
с:
//dt[. = 'cat2']/preceding-sibling::dd
Syl, Вы получили одно выражение XPath, который выбирает именно разыскиваемых узлов. Вместо этого вы решили принять более сложное, не переносимое и менее ремонтируемое решение, которое требует не только оценки XPath, но и дополнительного кода на языке хоста. –