XPath: выберите весь после одноуровневых элементов до другого одноуровневого элемента

Вот выборка моего 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()=''].

Как я могу достигнуть этого?

36
задан glmxndr 3 February 2010 в 08:29
поделиться

2 ответа

Вы могли бы сделать это так:

../node[not(text()) and preceding-sibling::node[@id][1][@id='1']]

где '1' - это идентификатор текущего узла (генерировать выражение динамически).

В выражении сказано:

  • из текущего контекста идут к родительскому
  • выделению тех дочерних узлов, которые
  • не имеют текста, а
  • из всех "предыдущих дочерних узлов, которые имеют id", первый должен иметь id 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']))" />
21
ответ дан 27 November 2019 в 06:13
поделиться

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, вам нужно было бы сбежать «<<» как «<<».

8
ответ дан 27 November 2019 в 06:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: