Voici un extrait de mon xml:
<node/>
<node/>
<node id="1">content</node>
<node/>
<node/>
<node/>
<node id="2">content</node>
<node/>
<node/>
Je suis positionné dans le node[@id='1']
. J'ai besoin d'un Xpath pour faire correspondre tous les éléments <node/>
Jusqu'au prochain nœud non vide (ici node[@id='2']
).
Edit: les attributs @id sont uniquement pour expliquer mon problème plus clairement, mais ne sont pas dans mon XML d'origine. J'ai besoin d'une solution qui n'utilise pas les attributs @id.
Je veux pas faire correspondre les frères et sœurs vides après node[@id='2']
, Donc je ne peux pas utiliser une following-sibling::node[text()='']
naïve.
Comment puis-je atteindre cet objectif ?
Vous pourriez le faire de cette façon:
../ nœud [pas (text ()) et précédent-frère :: nœud [@id] [1] [@ id = '1']]
où '1'
est l'id du noeud courant (générer l'expression dynamiquement).
L'expression dit:
Si vous êtes en XSLT, vous pouvez sélectionner dans l'axe frère suivant, car vous pouvez utiliser la fonction 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>
ou plus simple (et plus efficace) avec une clé:
<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']))" />
Plus simple que la réponse acceptée:
//node[@id='1']/following-sibling::node[following::node[@id='2']]
node
suivantsnode
avec id="2"
quelque part après eux.Montré en action avec un document de test plus clair (et des valeurs légales id
):
xml = '<root>
<node id="a"/><node id="b"/>
<node id="c">content</node>
<node id="d"/><node id="e"/><node id="f"/>
<node id="g">content</node>
<node id="h"/><node id="i"/>
</root>'
# A Ruby library that uses libxml2; http://nokogiri.org
require 'nokogiri'; doc = Nokogiri::XML(xml)
expression = "//node[@id='c']/following-sibling::node[following::node[@id='g']]"
puts doc.xpath(expression)
#=> <node id="d"/>
#=> <node id="e"/>
#=> <node id="f"/>
XPath 2.0 a les opérateurs "<<" et ">>" où node1 << node2
est vrai si node1 précède node2 dans l'ordre des documents. Donc, basé sur cela avec XPath 2.0 dans une feuille de style XSLT 2.0 où le nœud actuel est le nœud [@id = '1'] que vous pourriez utiliser
following-sibling::node[not(text()) and . << current()/following-sibling::node[@od][1]]
Cela nécessite également la fonction current () de XSLT, c'est pourquoi j'ai dit "avec XPath 2.0 dans une feuille de style XSLT 2.0". La syntaxe ci-dessus est XPath pur, dans une feuille de style XSLT, vous devez échapper "<<" en tant que "lt; lt;".