2010-02-01 5 views

Répondre

52

Si vous traduisez "ne sont pas des descendants" par "n'ont pas d'ancêtre", vous obtenez l'expression //*[not(ancestor::X)]. Cela retournera tous les nœuds dans un document, qui ne sont pas des descendants de nœuds nommés "X".

16

jarnbjo souligne la manière intuitive de faire ceci, pour utiliser //*[not(ancestor::X)]. Cela a le très grand mérite que cela fonctionnera indépendamment de la façon dont votre document est structuré, et c'est ce que vous devriez utiliser dans la plupart des circonstances. Mais si vous avez un document très volumineux, il peut être extrêmement inefficace. C'est une question très coûteuse. Il indique au processeur XPath de visiter chaque nœud du document et d'examiner son nœud ancêtre pour la présence d'un élément nommé X. Bien qu'il soit possible que le processeur XPath soit assez intelligent pour savoir qu'il n'a pas besoin de visiter les descendants de X pour évaluer cette requête, ce n'est pas probable.

Si vous avez des informations sur l'emplacement de l'élément X et que vous faites attention, vous pouvez écrire une requête plus efficace. Par exemple, si X est un enfant de l'élément de niveau supérieur, et il a beaucoup de descendants, ce sera beaucoup plus rapide:

/* | /*/* | /*/*[not(name()='X')]//* 

qui trouve l'élément de niveau supérieur, tous ses enfants immédiats, et les descendants de l'un de ses enfants immédiats non nommé X. Il n'examinera aucun des descendants de X.

De même, si vous savez que X est proche du bas de l'arbre, cette requête peut être plus efficace:

//*[not(ancestor::*[position() <= 3][X])] 

parce qu'il ne sera pas examiner l'ensemble de l'axe ancêtre pour chaque noeud il teste, juste ses trois derniers éléments. (Sauf si le processeur XPath est assez bête pour examiner chaque nœud sur un axe lorsqu'il effectue des tests qui utilisent position(), ce qui pourrait être le cas.)

Comme je l'ai dit, la plupart du temps, la version la plus simple va être la version la plus simple. mieux, et la plupart du temps c'est ce que je m'utiliserais moi-même.

Questions connexes