Я интерпретирую ваш "весь текст", чтобы он включал не только сами текстовые узлы, но и разметку, например <b>
. Я также предполагаю, что вы не хотите выбирать каждый узел-потомок между <start/>
и <end/>
, а только самые верхние. Кроме того, я предполагаю, что все теги <start/>
и <end/>
являются братьями и сестрами (не может быть на любом уровне).
Используйте следующий шаблон, чтобы выделить (и скопировать) весь текст между тегами <start/>
и <end/>
.
<xsl:template match="/">
<xsl:copy-of select="(//start)[1]/following-sibling::node()[not(self::end) and
name((preceding-sibling::start | preceding-sibling::end)[last()]) = 'start']"/>
</xsl:template>
Обновление:
Учитывая, что ваш начало / конец может быть на любом уровне, вы можете удалить -sibling
из осей выше:
select="(//start)[1]/following::node()[not(self::end) and
name((preceding::start | preceding::end)[last()]) = 'start']"
Однако это выбирает все узлы, а не только узлы верхнего уровня. (И поэтому, если вы глубоко скопируете выбранные узлы, вы получите дубликаты.) Это потому, что неясно определено, какое поведение должно произойти, если у вас было что-то вроде этого:
<start/>
<chapter>foo<end/></chapter>
Должен ли <chapter>
быть выбран или нет?
Однако, если вы можете наложить дополнительные ограничения на то, где начало / конец могут падать по отношению друг к другу, мы можем добиться большего. Например. каждый <end/>
родной брат предыдущего <start/>
? Если это так, вы могли бы сделать
<xsl:key name="text-by-last-milestone" match="* | text()"
use="generate-id((preceding-sibling::start | preceding-sibling::end)[last()])" />
<xsl:template match="/">
<xsl:for-each select="//start">
<xsl:copy-of select="key('text-by-last-milestone', generate-id())"/>
</xsl:for-each>
</xsl:template>
Если нет, то вам будет полезно показать более расширенный образец вашего ввода.
К вашему сведению, эти теги называются «вехой» разметки, поэтому вы можете найти больше информации об их обработке, выполнив поиск по этому термину. В зависимости от ограничений входного XML-кода они также рассматриваются как «одновременная разметка».