Wie gebe ich org.w3c.dom.Element im String-Format in Java aus?


88

Ich habe ein org.w3c.dom.ElementObjekt in meine Methode übergeben. Ich muss die gesamte XML-Zeichenfolge einschließlich ihrer untergeordneten Knoten (das gesamte Objektdiagramm) sehen. Ich suche nach einer Methode, mit der Elementich die Zeichenfolge in ein XML-Format konvertieren kann System.out.println. Nur println()für das 'Element'-Objekt funktioniert es nicht, da toString()das XML-Format nicht ausgegeben wird und der untergeordnete Knoten nicht durchlaufen wird. Gibt es einen einfachen Weg, ohne meine eigene Methode zu schreiben? Vielen Dank.

Antworten:


155

Angenommen, Sie möchten sich an die Standard-API halten ...

Sie könnten eine DOMImplementationLS verwenden :

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

Wenn Sie die Deklaration <? Xml version = "1.0" encoding = "UTF-16"?> Stört, können Sie stattdessen einen Transformator verwenden:

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
Dies ist die Lösung, wenn Sie [html: null] erhalten und den HTML-Code erwarten würden. Dieser Kommentar wurde hinzugefügt, damit Google die Antwort hoffentlich indizieren kann.
Donal Tobin

3
Sie können weiterhin LSSerializer verwenden und "UTF-8" ausgeben. Verwenden Sie stattdessen LSOutput mit StringWriter und setzen Sie den Codierungstyp auf "UTF- * 8"
Ricosrealm

1
Funktioniert auch mit dem w3c-Dokumentobjekt
3.

2
<?xml version="1.0" encoding="UTF-16"?>Erklärung stört ... wir können diese Zeile auch serializer .getDomConfig().setParameter("xml-declaration", false); in der ersten Lösung hinzufügen ....
Tarsem Singh

danke für deine antwort, das ist wirklich toll. Aber ich habe ein Problem damit, manchmal werden einige Tags der übereinstimmenden Teile entfernt und der Textinhalt von ihnen wird nur angezeigt. Haben Sie Vorschläge für dieses Problem?
Epcpu

16

Einfacher 4-Zeilen-Code zum Abrufen String ohne XML-Deklaration ( <?xml version="1.0" encoding="UTF-16"?>) vonorg.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

In der Standard-JAXP-API nicht unterstützt, habe ich zu diesem Zweck die JDom-Bibliothek verwendet. Es hat eine Druckerfunktion, Formatierungsoptionen usw. http://www.jdom.org/


+1, da dies nicht die Absicht der Standard-API org.w3c.dom ist. Wenn ich an XML-Blöcken als Text interessiert bin, versuche ich normalerweise nur, sie als Text mit einer Regex-Übereinstimmung zu analysieren (wenn die Suchkriterien leicht als Regex dargestellt werden können).
Cornel Masson

2

Wenn Sie das XML-Schema haben oder auf andere Weise JAXB-Bindungen dafür erstellen können, können Sie mit dem JAXB-Marshaller in System.out schreiben:

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

Probieren Sie jcabi-xml mit einem Liner aus:

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

Neue Versionen von jcabi-xml unterstützen Element nicht als Parameter, sondern nur Node / File / String.
Ermintar

1

Das wird in jcabi gemacht:

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

und es funktioniert bei mir!


0

Mit VTD-XML können Sie den Cursor übergeben und einen einzelnen getElementFragment-Aufruf ausführen, um das Segment abzurufen (wie durch seinen Versatz und seine Länge angegeben). Nachfolgend finden Sie ein Beispiel

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

}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.