Come posso visualizzare org.w3c.dom.Element in formato stringa in java?


89

Ho un org.w3c.dom.Elementoggetto passato nel mio metodo. Ho bisogno di vedere l'intera stringa xml compresi i suoi nodi figlio (l'intero oggetto grafico). Sto cercando un metodo che possa convertire il Elementin una stringa di formato xml su cui posso farlo System.out.println. Solo println()sull'oggetto 'Elemento' non funzionerà perché toString()non produrrà il formato xml e non passerà attraverso il suo nodo figlio. C'è un modo semplice senza scrivere il mio metodo per farlo? Grazie.

Risposte:


155

Supponendo che tu voglia restare con l'API standard ...

Potresti usare un DOMImplementationLS :

Document document = node.getOwnerDocument();
DOMImplementationLS domImplLS = (DOMImplementationLS) document
    .getImplementation();
LSSerializer serializer = domImplLS.createLSSerializer();
String str = serializer.writeToString(node);

Se la dichiarazione <? Xml version = "1.0" encoding = "UTF-16"?> Ti dà fastidio, potresti utilizzare un trasformatore :

TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
StringWriter buffer = new StringWriter();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.transform(new DOMSource(node),
      new StreamResult(buffer));
String str = buffer.toString();

7
Questa è la soluzione se stai ottenendo [html: null] e ti aspetti l'HTML. Aggiunto questo commento in modo che Google possa indicizzare la risposta, si spera.
Donal Tobin

3
È comunque possibile utilizzare LSSerializer e visualizzare "UTF-8". Utilizza invece LSOutput con StringWriter e imposta il tipo di codifica su "UTF- * 8"
ricosrealm

1
Funziona anche con l'oggetto Documento w3c
2013

2
<?xml version="1.0" encoding="UTF-16"?>la dichiarazione dà fastidio ... possiamo anche aggiungere questa riga serializer .getDomConfig().setParameter("xml-declaration", false); nella prima soluzione ...
Tarsem Singh

grazie per la tua risposta, è davvero fantastico. Ma ho un problema con esso, a volte alcuni tag delle parti corrispondenti vengono rimossi e il loro contenuto di testo viene visualizzato esclusivamente. Hai suggerimenti per questo problema?
epcpu

16

Semplice codice di 4 righe da ottenere String senza xml-declaration ( <?xml version="1.0" encoding="UTF-16"?>)org.w3c.dom.Element

DOMImplementationLS lsImpl = (DOMImplementationLS)node.getOwnerDocument().getImplementation().getFeature("LS", "3.0");
LSSerializer serializer = lsImpl.createLSSerializer();
serializer.getDomConfig().setParameter("xml-declaration", false); //by default its true, so set it to false to get String without xml-declaration
String str = serializer.writeToString(node);

2

Non supportato nell'API JAXP standard, ho utilizzato la libreria JDom per questo scopo. Ha una funzione stampante, opzioni di formattazione ecc. Http://www.jdom.org/


+1 per non essere l'intento dell'API org.w3c.dom standard. Se sono interessato a blocchi di XML come testo, di solito provo solo ad analizzarlo come testo con una corrispondenza regex (se i criteri di ricerca sono facilmente rappresentati come regex).
Cornel Masson

2

Se hai lo schema dell'XML o puoi creare in altro modo collegamenti JAXB per esso, puoi utilizzare JAXB Marshaller per scrivere su System.out:

import javax.xml.bind.*;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;

@XmlRootElement
public class BoundClass {

    @XmlAttribute
    private String test;

    @XmlElement
    private int x;

    public BoundClass() {}

    public BoundClass(String test) {
        this.test = test;
    }

    public static void main(String[] args) throws Exception {
        JAXBContext jxbc = JAXBContext.newInstance(BoundClass.class);
        Marshaller marshaller = jxbc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
        marshaller.marshal(new JAXBElement(new QName("root"),BoundClass.class,new Main("test")),System.out);
    }
}

2

Prova jcabi-xml con una fodera:

String xml = new XMLDocument(element).toString();

Le nuove versioni di jcabi-xml non supportano Element come parametro, solo Node / File / String.
Ermintar

1

questo è ciò che viene fatto in jcabi:

private String asString(Node node) {
    StringWriter writer = new StringWriter();
    try {
        Transformer trans = TransformerFactory.newInstance().newTransformer();
        // @checkstyle MultipleStringLiterals (1 line)
        trans.setOutputProperty(OutputKeys.INDENT, "yes");
        trans.setOutputProperty(OutputKeys.VERSION, "1.0");
        if (!(node instanceof Document)) {
            trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        }
        trans.transform(new DOMSource(node), new StreamResult(writer));
    } catch (final TransformerConfigurationException ex) {
        throw new IllegalStateException(ex);
    } catch (final TransformerException ex) {
        throw new IllegalArgumentException(ex);
    }
    return writer.toString();
}

e funziona per me!


0

Con VTD-XML , puoi passare al cursore ed effettuare una singola chiamata getElementFragment per recuperare il segmento (come indicato dal suo offset e lunghezza) ... Di seguito è riportato un esempio

import com.ximpleware.*;
public class concatTest{
    public static void main(String s1[]) throws Exception {
        VTDGen vg= new VTDGen();
        String s = "<users><user><firstName>some </firstName><lastName> one</lastName></user></users>";
        vg.setDoc(s.getBytes());
        vg.parse(false);
        VTDNav vn = vg.getNav();
        AutoPilot ap = new AutoPilot(vn);
        ap.selectXPath("/users/user/firstName");
        int i=ap.evalXPath();
        if (i!=1){
            long l= vn.getElementFragment();
            System.out.println(" the segment is "+ vn.toString((int)l,(int)(l>>32)));
        }
    }

}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.