web-dev-qa-db-fra.com

XPath pour obtenir tous les nœuds enfants (éléments, commentaires et texte) sans parent

J'ai besoin d'un XPath pour récupérer tous les ChildNodes (y compris l'élément de texte, l'élément de commentaire et les éléments enfants) sans élément parent. De l'aide

Exemple d'échantillon:

<DOC>
<PRESENTEDIN>
    <X>
        First Text Node #1 
        <y> Y can Have Child Nodes # 
            <child> deep to it </child> 
         </y>
         Second Text Node #2 <z/> 
    </X>
    <EVTS>
        <evt/>
        <evt>
            <mtg_descr> SAE 2006 World Congress &amp; Exhibition </mtg_descr>
            <sess_descr> Advanced Hybrid Vehicle Powertrains (Part 1 of 5) </sess_descr>
            <loc> Detroit,MI,United States </loc>
            <sess_prod_grp_cd> TSESS </sess_prod_grp_cd>
            <sess_evt_name> P13 </sess_evt_name>
            <sess_gen_num> 138352 </sess_gen_num>
            <mtg_start_dt> 04/03/2006 </mtg_start_dt>
            <mtg_end_dt> 04/06/2006 </mtg_end_dt>
            <desig> CONGRESS-2006 </desig>
        </evt>
    </EVTS>
    <EVTTYPE>PAPER</EVTTYPE>
    <SUPERTECH>
        <![CDATA[C8585]]>
    </SUPERTECH>
</PRESENTEDIN>

XPATH ESSAYÉ

   1. $doc/PRESENTEDIN/X
   2. $doc/PRESENTEDIN/X/descendant::*
   2. $doc/PRESENTEDIN/X/self::*

PRODUCTION ATTENDUE

    First Text Node #1 
    <y> Y can Have Child Nodes # 
        <child> deep to it </child> 
     </y>
     Second Text Node #2 <z/> 

Je ne veux pas

<X>
  First Text Node #1 
        <y> Y can Have Child Nodes # 
            <child> deep to it </child> 
         </y>
         Second Text Node #2 <z/> 
</X>
51
kadalamittai

De la documentation de XPath ( http://www.w3.org/TR/xpath/#location-paths ):

child::* Sélectionne tous les enfants d'élément du nœud de contexte

child::text() sélectionne tous les enfants de noeud de texte du noeud de contexte

child::node() sélectionne tous les enfants du noeud contextuel, quel que soit leur type

Donc, je suppose que votre réponse est la suivante:

$doc/PRESENTEDIN/X/child::node()

Et si vous voulez un tableau aplati de tous les nœuds imbriqués:

$doc/PRESENTEDIN/X/descendant::node()
67
linepogl

Utilisez cette expression XPath :

/*/*/X/node()

Ceci sélectionne tout nœud (élément, nœud de texte, commentaire ou instruction de traitement) qui est un enfant de tout élément X et qui est un petit-fils de l'élément supérieur du document XML.

Pour vérifier ce qui est sélectionné , voici cette transformation XSLT qui génère exactement les nœuds sélectionnés:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes"/>
 <xsl:template match="/">
  <xsl:copy-of select="/*/*/X/node()"/>
 </xsl:template>
</xsl:stylesheet>

et il produit exactement le résultat voulu et correct:

   First Text Node #1            
    <y> Y can Have Child Nodes #                
        <child> deep to it </child>
    </y>            Second Text Node #2 
    <z />

Explication :

  1. Comme défini dans la spécification W3 XPath 1., "child::node()" sélectionne tous les enfants du noeud de contexte. , quel que soit leur type de noeud. " Cela signifie que tous les enfants d'élément, de nœud de texte, de nœud de commentaire et de nœud d'instruction de traitement sont sélectionnés par ce nœud-test.

  2. node() est une abréviation de child::node() (car child:: est l'axe principal et est utilisé lorsqu'aucun axe n'est spécifié explicitement).

23
Dimitre Novatchev