2011-05-14 10 views
6

Ésta es una parte de mi XML:Usando XPath y ETV-XML para obtener subnodos y texto de un elemento como una cadena

<MAIN> 
    <L> 
     <D>string1 string2 <b>string3</b> string4</D> 
    </L> 
    <L> 
     <D>string5 string6 <b>string7</b> string8 <i>string9</i></D> 
    </L> 
</MAIN> 

I want to get the content of all the <D> tags as string. So, the example above should return: 

1st iteration: 'string1 string2 <b>string3</b> string4' 
2nd iteration: 'string5 string6 <b>string7</b> string8 <i>string9</i>' 
etc... 

en la ETV-xml utilicé un piloto automático con XPath "L ///D "y" // L/D/text() "pero eso no funcionó.

Cualquier consejo o enfoque alternativo será apreciado.

Saludos

+0

¿No puede simplemente usar // L que devolverá una lista de nodos. Luego, para esos nodos, haga un bucle sobre los hijos directos y llame a cualquier método que devuelva el Texto. – gshauger

+0

Buena pregunta, +1. Vea mi respuesta para una solución completa y corta de expresión de XPath de una sola línea. –

Respuesta

12

A continuación se muestra el código que hace lo que busca.

VTDGen vg = new VTDGen(); 
    if (vg.parseFile("c://xml//alex.txt", true)){ 
     VTDNav vn = vg.getNav(); 
     AutoPilot ap = new AutoPilot(vn); 
     ap.selectXPath("//L/D"); 
     int i=-1; 
     while((i=ap.evalXPath())!=-1){ 
      long l = vn.getContentFragment(); 
      System.out.println(" -==> "+ vn.toString((int)l, (int)(l>>32))); 
     } 
    } 
+0

¡Muchas gracias! Esto solucionó mi problema. – Alex

+0

@alex, ¡eres bienvenido! –

+0

Empecé a usar este enfoque, pero parece estropear los caracteres escapados. Por ejemplo, si el contenido tiene '&', la cadena impresa solo tiene "&". Me encontré con un problema con esto, y lo publiqué como una pregunta separada [aquí] (http://stackoverflow.com/questions/27823107/vtd-xml-seems-to-be-spoiling-escaped-string-in-xml -documento). –

3

Uso:

/*/L/D/node() 

Esto selecciona todos los nodos (elementos, texto-nodos, procesamiento-instrucciones y comment-nodos) que son hijos de cualquier elemento D que es un niño de cualquier elemento L que sea secundario del elemento superior del documento XML.

Como alternativa, puede seleccionar por separado todos los nodos-hijos de los dos /*/L/D elementos:

/*/L[1]/D/node() 

y

/*/L[2]/D/node() 

Verificación mediante XSLT como anfitrión de XPath:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:copy-of select="/*/L[1]/D/node()"/> 
-------------------- 
    <xsl:copy-of select="/*/L[2]/D/node()"/> 
</xsl:template> 
</xsl:stylesheet> 

cuando se aplica en el documento XML proporcionado:

<MAIN> 
    <L> 
     <D>string1 string2 
      <b>string3</b> string4 
     </D> 
    </L> 
    <L> 
     <D>string5 string6 
      <b>string7</b> string8 
      <i>string9</i> 
     </D> 
    </L> 
</MAIN> 

el resultado deseado, correcta se produce:

string1 string2 
      <b>string3</b> string4 

-------------------- 
    string5 string6 
      <b>string7</b> string8 
      <i>string9</i> 
+0

Gracias por su respuesta. Esto no funcionó. Se repite a través de los nodos dentro de las etiquetas D, por lo que en la primera etiqueta D va a la etiqueta b y en la segunda etiqueta D va primero a la etiqueta b y luego a la etiqueta i. – Alex

+0

@Alex: si este es el caso, entonces no está utilizando una implementación compatible con XPath: el nodo 'test' node() 'debe seleccionar todos los elementos secundarios del nodo actual, no solo los elementos. Sospecho que solo inspecciona los elementos de la lista de nodos resultante cuando la acción correcta es inspeccionar todos los nodos seleccionados. –

+0

@alex, ¿es un error de vtd-xml? –

Cuestiones relacionadas