Принятый ответ имеет плохой побочный эффект, и это своего рода неправильно.
Далее в этом посте я объясню реальное сравнение следующего существенного утверждения и почему оно может и потерпит неудачу .
пересмотреть / проанализировать ситуацию, находясь в шаблоне <xsl:template match="h1">
:
- Текущий контекстный узел - это любой
h1
из соответствующего <xsl:template>
.
- переменная с именем
header
содержит копию моего текущего узла контекста.
Существенное утверждение, которое является плохим / неправильным:
follow-sibling :: p [previousing-sibling :: h1 [1] = $ header]
- выбрать всех следующих братьев и сестер
p
моего контекстного узла | following-sibling::p
- отфильтруйте эти
p
, где первый (ближайший) предшествующий брат с именем h1
"равен" так же, как переменная $header
| ...[preceding-sibling::h1[1] = $header]
.
!! В XSLT 1.0 сравнение узла с узлом будет выполняться по его значению !!
Посмотрите это на примере. Давайте представим, что входной xml выглядит следующим образом [<h1>
содержит дважды одинаковое значение Test
]:
<html>
<h1>Test</h1>
<p>Test: p 1</p>
<p>Test: p 2</p>
<h1>Test</h1>
<p>Test2: p 1</p>
<p>Test2: p 2</p>
<p>Test2: p 3</p>
</html>
A ! WRONG! будет создан результат:
<content>
<section>
<sectionHeading>Test</sectionHeading>
<sectionContent>
<paragraph>Test: p 1</paragraph>
<paragraph>Test: p 2</paragraph>
<paragraph>Test2: p 1</paragraph> <-- should be only in 2. section
<paragraph>Test2: p 2</paragraph> <-- should be only in 2. section
<paragraph>Test2: p 3</paragraph> <-- should be only in 2. section
</sectionContent>
</section>
<section>
<sectionHeading>Test</sectionHeading>
<sectionContent>
<paragraph>Test2: p 1</paragraph>
<paragraph>Test2: p 2</paragraph>
<paragraph>Test2: p 3</paragraph>
</sectionContent>
</section>
</content>
Правильное сравнение
...
<xsl:template match="h1">
<xsl:variable name="header" select="generate-id(.)"/>
<section>
<sectionHeading>
<xsl:apply-templates/>
</sectionHeading>
<sectionContent>
<xsl:for-each select="following-sibling::p[generate-id(preceding-sibling::h1[1]) = $header]">
<paragraph>
<xsl:value-of select="."/>
</paragraph>
</xsl:for-each>
</sectionContent>
</section>
</xsl:template>
...
Используйте функцию generate-id () , чтобы получить уникальный (по крайней мере, в текущем документе) идентификатор узла и сравнить теперь узел с узлом! Даже если вы используете эту технику с <xsl:key>
, вы должны использовать generate-id()
.