Вот выборка моего xml:
<node/>
<node/>
<node id="1">content</node>
<node/>
<node/>
<node/>
<node id="2">content</node>
<node/>
<node/>
Я расположен в node[@id='1']
. Мне нужен Xpath для соответствия весь <node/>
элементы до следующего не пустой узел (здесь node[@id='2']
).
Править: атрибуты @id только для объяснения моей проблемы более ясно, но не находятся в моем исходном XML. Мне нужно решение, которое не использует атрибуты @id.
Я не хочу соответствовать пустым одноуровневым элементам после node[@id='2']
, таким образом, я не могу использовать наивное following-sibling::node[text()='']
.
Как я могу достигнуть этого?
Вы могли бы сделать это так:
../node[not(text()) and preceding-sibling::node[@id][1][@id='1']]
где '1'
- это идентификатор текущего узла (генерировать выражение динамически).
В выражении сказано:
Если вы находитесь в XSLT, вы можете выбрать из оси following-sibling, потому что вы можете использовать функцию current()
:
<!-- the for-each is merely to switch the current node -->
<xsl:for-each select="node[@id='1']">
<xsl:copy-of select="
following-sibling::node[
not(text()) and
generate-id(preceding-sibling::node[@id][1])
=
generate-id(current())
]
" />
</xsl:for-each>
или проще (и эффективнее) с помощью ключа:
<xsl:key
name="kNode"
match="node[not(text())]"
use="generate-id(preceding-sibling::node[@id][1])"
/>
<xsl:copy-of select="key('kNode', generate-id(node[@id='1']))" />
XPath 2.0 имеет операторы «<<» и «>>», где Node1 << Node2
верно, если Node1 предшествует Node2 в порядке документа.
Таким образом, основываясь на этом с XPath 2.0 в стиле XSLT 2.0, где текущий узел является узлом [@ID = '1'], вы можете использовать
following-sibling::node[not(text()) and . << current()/following-sibling::node[@od][1]]
, который также нуждается в текущей () функции от XSLT, так что именно поэтому я сказал «С XPath 2.0 в стиле XSLT 2.0». Синтаксис выше является чистым XPath, в стиле XSLT, вам нужно было бы сбежать «<<» как «<<».