Это выражение XPath 2.0
/root/(
for $a in A,
$b in B[concat('#', @xml:id) = $a/@ref][1]
return .//text()[$b >> .][. >> $a]
)
Выбирает этот текстовые узлы (добавлена цитата для ясности):
' interesting '
'text'
' no 1 '
' interesting text no 2 '
Тест в https://xsltfiddle.liberty -development.net / bFN1y9t
Обратите внимание : использование for
выражения для "внутреннего соединения".
В XPath 1.0 нет способа объявить замыкание, поэтому нет и способа сделать «внутреннее соединение». Но если вы уверены, что между начальными и конечными отметками нет совпадений, вы можете использовать:
/root//text()[
(preceding::A|preceding::B)[last()][self::A]
][(following::A|following::B)[1][self::B]
]
или
/root//text()[
preceding::*[self::A|self::B][1][self::A]
][following::*[self::A|self::B][1][self::B]
]
Тест в http://www.xpathtester.com/xpath/a3051d2ad3af3423502b221bef6a580e
Отредактированный вопрос
Я ищу команду xPath, которая выбирает для каждого
элемент "A" с атрибутом "ref" узлы, следующие за этим элементом
до определенного элемента "B" с идентификатором, указанным в "ref".
Если вы хотите теперь узлы вместо текстовых узлов-потомков, просто замените путь в выражении:
XPath 2.0 выражение
/root/(
for $a in A,
$b in B[concat('#', @xml:id) = $a/@ref][1]
return node()[$b >> .][. >> $a]
)
XPath 1.0 выражение
/root/node()[
(preceding::A|preceding::B)[last()][self::A]
][(following::A|following::B)[1][self::B]
]