2011-02-25 24 views
39

Necesito un XPath para buscar todos los ChildNodes (incluido el elemento de texto, elemento de comentario & elementos secundarios) sin elemento primario. Cualquier ayudaXPath para obtener todos los nodos secundarios (elementos, comentarios y texto) sin padre

Muestra Ejemplo:

<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 TRIED

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

OUTPUT ESPERADO

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

no quiero

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

Respuesta

51

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

child::* selecciona todo el elemento hijos del nodo de contexto

child::text() selecciona todos los nodos de texto hijos del nodo de contexto

child::node() selecciona todos los niños del contexto t nodo, sea cual sea su tipo de nodo

así que supongo que la respuesta es:

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

Y si quieres una matriz aplanada de todos los nodos anidados:

$doc/PRESENTEDIN/X/descendant::node() 
+0

correcta pero no consultar también la [abreviado sintaxis] (http://www.w3.org/TR/xpath/#path-abbrev) –

+0

Gracias que resuelve mi duda. Muchas gracias. – kadalamittai

+0

Estoy usando esto para copiar todos los nodos secundarios, pero a la salida cada elemento secundario está marcado con un identificador de espacio de nombres; ¿hay alguna forma de desactivarlo? – raffian

20

Utilice esta Expresión de XPath:

/*/*/X/node() 

Esto selecciona cualquier nodo (elemento, nodo de texto, comentario o instrucción de procesamiento) que sea hijo de cualquier elemento X que sea un elemento secundario del elemento superior del documento XML.

Para verificar lo que se ha seleccionado, aquí está esta transformación XSLT que emite exactamente los nodos seleccionados:

<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> 

y produce exactamente, resultado correcto deseada:

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

Explicación:

  1. Tal como se define en el W3 XPath 1.0 Spec, "child::node() selecciona todos los hijos del nodo de contexto, cualquiera que sea su tipo de nodo."Esto significa que los niños de elemento, texto-nodo, comentario-nodo y instrucción de procesamiento de nodos son seleccionados por este nodo-test.

  2. node() es una abreviatura de child::node() (porque child:: es el eje principal y se utiliza cuando ningún eje se especifica explícitamente).

+0

+1 para una buena solución. – Flack

+0

@DimitreNovatchev Vuelta viejos días: p Gracias maneras – Nabin

+0

@Spiderman, sí, ¿deberíamos sentir nostalgia? Ahora tenemos XSLT 3.0 y XPath 3.1 –

Cuestiones relacionadas