2011-10-27 28 views
6

Estoy escribiendo una aplicación en Java usando import org.jdom. *;Cómo obtener los contenidos del nodo de JDOM

Mi XML es válido, pero a veces contiene etiquetas HTML. Por ejemplo, algo como esto:

<program-title>Anatomy &amp; Physiology</program-title> 
    <overview> 
     <content> 
       For more info click <a href="page.html">here</a> 
       <p>Learn more about the human body. Choose from a variety of Physiology (A&amp;P) designed for complementary therapies.&amp;#160; Online studies options are available.</p> 
     </content> 
    </overview> 
    <key-information> 
    <category>Health &amp; Human Services</category> 

Así que mi problema es con el < p> etiquetas dentro del nodo overview.content.

Tenía la esperanza de que este código funcionaría:

 Element overview = sds.getChild("overview"); 
     Element content = overview.getChild("content"); 

     System.out.println(content.getText()); 

pero vuelve en blanco.

¿Cómo devuelvo todo el texto (etiquetas anidadas y todo) del nodo overview.content?

Gracias

+0

Hola, ¿cómo puedo aplanar el nodo de contenido de forma recurrente, cuando el texto se mezcla con otros nodos. Por ejemplo, un hipervínculo se encuentra en el medio de una oración. He agregado una recompensa por algo de ayuda. –

+0

Necesita obtener todo el código HTML dentro de la etiqueta de contenido, incluidos los enlaces y las listas ordenadas. Gracias –

Respuesta

0

El problema es que el nodo <content> no tiene un niño de texto; tiene un hijo <p> que contiene texto.

Prueba esto:

Element overview = sds.getChild("overview"); 
Element content = overview.getChild("content"); 
Element p = content.getChild("p"); 
System.out.println(p.getText()); 

Si desea que todos los nodos secundarios inmediatos, llame p.getChildren(). Si desea obtener TODOS los nodos secundarios, tendrá que llamarlo recursivamente.

+0

Y luego simplemente convertir manualmente los nodos de tipo Elemento en representación textual ... Probablemente más simple de lo que tenía en mente. –

4

Puede intentar usar method getValue() para la aproximación más cercana, pero lo que hace es concatenar todo el texto dentro del elemento y los descendientes juntos. Esto no le dará la etiqueta <p> en ninguna forma. Si esa etiqueta está en su XML como lo ha mostrado, se ha convertido en parte del marcado XML. Tendría que estar incluido como &lt;p&gt; o incrustrado en una sección CDATA para ser tratado como texto.

Como alternativa, si conoce todos los elementos que pueden aparecer o no en su XML, puede aplicar una transformación XSLT que convierta las cosas que no están destinadas a la escritura en texto sin formato.

+0

Respuesta perfecta para aquellos que no necesitan los nombres de los elementos en el contenido mixto. ¡Gracias! –

16

content.getText() da texto inmediato que solo es útil bien con los elementos de hoja con contenido de texto.

truco es utilizar org.jdom.output.XMLOutputter (con el modo de texto CompactFormat)

public static void main(String[] args) throws Exception { 
    SAXBuilder builder = new SAXBuilder(); 
    String xmlFileName = "a.xml"; 
    Document doc = builder.build(xmlFileName); 

    Element root = doc.getRootElement(); 
    Element overview = root.getChild("overview"); 
    Element content = overview.getChild("content"); 

    XMLOutputter outp = new XMLOutputter(); 

    outp.setFormat(Format.getCompactFormat()); 
    //outp.setFormat(Format.getRawFormat()); 
    //outp.setFormat(Format.getPrettyFormat()); 
    //outp.getFormat().setTextMode(Format.TextMode.PRESERVE); 

    StringWriter sw = new StringWriter(); 
    outp.output(content.getContent(), sw); 
    StringBuffer sb = sw.getBuffer(); 
    System.out.println(sb.toString()); 
} 

salida

For more info click<a href="page.html">here</a><p>Learn more about the human body. Choose from a variety of Physiology (A&amp;P) designed for complementary therapies.&amp;#160; Online studies options are available.</p> 

hacer Explora otros formatting opciones y modificar el código anterior a su necesidad.

"clase para encapsular las opciones de formato XMLOutputter. Los usuarios típicos pueden utilizar las configuraciones estándar de formato obtenidos por getRawFormat() (sin cambios de espacio en blanco), getPrettyFormat() (embellecimiento de los espacios en blanco), y getCompactFormat() (normalización espacio en blanco)."

+0

Gracias hombre !! –

3

Bueno, tal vez eso es lo que necesita:

import java.io.StringReader; 

import org.custommonkey.xmlunit.XMLTestCase; 
import org.custommonkey.xmlunit.XMLUnit; 
import org.jdom.input.SAXBuilder; 
import org.jdom.output.XMLOutputter; 
import org.testng.annotations.Test; 
import org.xml.sax.InputSource; 

public class HowToGetNodeContentsJDOM extends XMLTestCase 
{ 
    private static final String XML = "<root>\n" + 
      " <program-title>Anatomy &amp; Physiology</program-title>\n" + 
      " <overview>\n" + 
      "  <content>\n" + 
      "    For more info click <a href=\"page.html\">here</a>\n" + 
      "    <p>Learn more about the human body. Choose from a variety of Physiology (A&amp;P) designed for complementary therapies.&amp;#160; Online studies options are available.</p>\n" + 
      "  </content>\n" + 
      " </overview>\n" + 
      " <key-information>\n" + 
      "  <category>Health &amp; Human Services</category>\n" + 
      " </key-information>\n" + 
      "</root>"; 
    private static final String EXPECTED = "For more info click <a href=\"page.html\">here</a>\n" + 
      "<p>Learn more about the human body. Choose from a variety of Physiology (A&amp;P) designed for complementary therapies.&amp;#160; Online studies options are available.</p>"; 

    @Test 
    public void test() throws Exception 
    { 
     XMLUnit.setIgnoreWhitespace(true); 
     Document document = new SAXBuilder().build(new InputSource(new StringReader(XML))); 
     List<Content> content = document.getRootElement().getChild("overview").getChild("content").getContent(); 
     String out = new XMLOutputter().outputString(content); 
     assertXMLEqual("<root>" + EXPECTED + "</root>", "<root>" + out + "</root>"); 
    } 
} 

Salida:

PASSED: test on instance null(HowToGetNodeContentsJDOM) 

=============================================== 
    Default test 
    Tests run: 1, Failures: 0, Skips: 0 
=============================================== 

estoy usando jdom con los genéricos: http://www.junlu.com/list/25/883674.html

Editar: En realidad eso no es mucho diferente de la respuesta de Prashant Bhate. Tal vez necesites decirnos qué es lo que te estás perdiendo ...

0

No es especialmente bonita, pero funciona bien (usando JDOM API): solución

public static String getRawText(Element element) { 
    if (element.getContent().size() == 0) { 
     return ""; 
    } 

    StringBuffer text = new StringBuffer(); 
    for (int i = 0; i < element.getContent().size(); i++) { 
     final Object obj = element.getContent().get(i); 
     if (obj instanceof Text) { 
      text.append(((Text) obj).getText()); 
     } else if (obj instanceof Element) { 
      Element e = (Element) obj; 
      text.append("<").append(e.getName()); 
      // dump all attributes 
      for (Attribute attribute : (List<Attribute>)e.getAttributes()) { 
       text.append(" ").append(attribute.getName()).append("=\"").append(attribute.getValue()).append("\""); 
      } 
      text.append(">"); 
      text.append(getRawText(e)).append("</").append(e.getName()).append(">"); 
     } 
    } 
    return text.toString(); 
} 

de Prashant Bhate es mejor, aunque!

1

Si también está generando el archivo XML, debe poder encapsular sus datos html en <![CDATA[]]> para que el analizador XML no lo analice.

+0

No, lamentablemente no genero el XML, solo tengo que consumirlo. –

0

Si desea emitir el contenido de algún nodo JSOM sólo tiene que utilizar

System.out.println(new XMLOutputter().outputString(node)) 
Cuestiones relacionadas