2011-10-27 15 views
6

Sto scrivendo un'applicazione in java utilizzando import org.jdom. *;Come ottenere il contenuto del nodo da JDOM

Il mio XML è valido, ma a volte contiene tag HTML. Per esempio, qualcosa di simile:

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

Quindi il mio problema è con il < p> tag all'interno del nodo overview.content.

Speravo che questo codice dovrebbe funzionare:

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

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

ma restituisce vuoto.

Come restituire tutto il testo (tag nidificati e tutto) dal nodo overview.content?

Grazie

+0

Ciao, come posso appiattire il nodo del contenuto fuori in modo ricorsivo, quando il testo viene mescolato con altri nodi. Ad esempio, un collegamento ipertestuale si trova nel mezzo di una frase. Ho aggiunto una taglia per un po 'di aiuto. –

+0

È necessario ottenere tutto il codice HTML all'interno del tag del contenuto, inclusi collegamenti e elenchi ordinati. Grazie –

risposta

0

Il problema è che il nodo <content> non ha un bambino di testo; ha un bambino <p> che sembra contenere testo.

Prova questa:

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

Se si desidera che tutti i nodi figlio immediati, chiamare p.getChildren(). Se si desidera ottenere TUTTI i nodi figlio, sarà necessario chiamarlo in modo ricorsivo.

+0

E poi basta trasformare manualmente i nodi tipo Element in rappresentazione testuale ... Probabilmente più semplice di quello che avevo in mente. –

4

Si potrebbe provare a utilizzare method getValue() per l'approssimazione più vicina, ma ciò che fa è concatenare tutto il testo all'interno dell'elemento e discendenti insieme. Questo non ti darà il tag <p> in nessun modo. Se quel tag è nel tuo XML come hai mostrato, è diventato parte del markup XML. Dovrebbe essere incluso come &lt;p&gt; o incorporato in una sezione CDATA per essere trattato come testo.

In alternativa, se si conoscono tutti gli elementi che possono o non possono essere visualizzati nel proprio XML, è possibile applicare una trasformazione XSLT che trasforma elementi che non sono intesi come markup in testo normale.

+0

Risposta perfetta per coloro che non hanno bisogno dei nomi degli elementi nei contenuti misti. Grazie! –

16

content.getText() fornisce un testo immediato che è utile solo bene con gli elementi foglia con contenuto di testo.

trucco è quello di utilizzare org.jdom.output.XMLOutputter (con modalità testo 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()); 
} 

uscita

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> 

fare Esplora altre formatting opzioni e modificare il codice qui sopra per il vostro bisogno.

"classe per incapsulare opzioni di formato XMLOutputter. Gli utenti tipici possono utilizzare le configurazioni standard di formato ottenuti dalla getRawFormat() (nessuna modifica spazi bianchi), getPrettyFormat() (abbellimento spazi bianchi), e getCompactFormat() (normalizzazione spazi bianchi)."

+0

Grazie amico !! –

3

Beh, forse questo è quello che vi serve:

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>"); 
    } 
} 

uscita:

PASSED: test on instance null(HowToGetNodeContentsJDOM) 

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

Sto usando JDOM con i generici: http://www.junlu.com/list/25/883674.html

Edit: In realtà questo non è più di tanto diverso dalla risposta di Prashant Bhate. Forse hai bisogno di dirci cosa ti manca ...

0

Non particolarmente bella, ma funziona bene (usando JDOM API): soluzione

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(); 
} 

Prashant di Bhate è più bello però!

1

Se si sta generando il file XML, si dovrebbe essere in grado di incapsulare i dati html in <![CDATA[]]> in modo che non venga analizzato dal parser XML.

+0

No, sfortunatamente non genero l'XML, devo solo consumarlo. –

0

Se si desidera emettere il contenuto di qualche nodo JSOM basta usare

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