Ich benötige einen XPath, um alle ChildNodes (einschließlich Textelement, Kommentarelement und Child-Elemente) ohne Parent-Element abzurufen. Irgendeine Hilfe
Beispielbeispiel:
<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 & 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 VERSUCHT
1. $doc/PRESENTEDIN/X
2. $doc/PRESENTEDIN/X/descendant::*
2. $doc/PRESENTEDIN/X/self::*
ERWARTETE AUSGABE
First Text Node #1
<y> Y can Have Child Nodes #
<child> deep to it </child>
</y>
Second Text Node #2 <z/>
Ich will nicht
<X>
First Text Node #1
<y> Y can Have Child Nodes #
<child> deep to it </child>
</y>
Second Text Node #2 <z/>
</X>
Aus der Dokumentation von XPath ( http://www.w3.org/TR/xpath/#location-paths ):
child::*
Wählt alle untergeordneten Elemente des Kontextknotens aus
child::text()
wählt alle untergeordneten Textknoten des Kontextknotens aus
child::node()
wählt alle untergeordneten Knoten des Kontextknotens aus, unabhängig von ihrem Knotentyp
Ich denke, Ihre Antwort lautet:
$doc/PRESENTEDIN/X/child::node()
Und wenn Sie ein abgeflachtes Array aller verschachtelten Knoten möchten:
$doc/PRESENTEDIN/X/descendant::node()
Verwenden Sie diesen XPath-Ausdruck :
/*/*/X/node()
Dies wählt jeden Knoten (Element, Textknoten, Kommentar oder Verarbeitungsanweisung) aus, der ein untergeordnetes Element eines X
-Elements ist, das ein untergeordnetes Element des obersten Elements des XML-Dokuments ist.
Um zu überprüfen, was ausgewählt ist , gibt diese XSLT-Transformation genau die ausgewählten Knoten aus:
<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>
und es ergibt genau das gewünschte, korrekte Ergebnis:
First Text Node #1
<y> Y can Have Child Nodes #
<child> deep to it </child>
</y> Second Text Node #2
<z />
Erklärung :
Wie in der W3 XPath 1. Spezifikation definiert, wählt "child::node()
alle untergeordneten Elemente des Kontextknotens aus , unabhängig von ihrem Knotentyp. " Dies bedeutet, dass alle untergeordneten Elemente, Textknoten, Kommentarknoten und Verarbeitungsanweisungsknoten von diesem Knotentest ausgewählt werden.
node()
ist eine Abkürzung für child::node()
(da child::
die primäre Achse ist und verwendet wird, wenn keine Achse explizit angegeben ist).