web-dev-qa-db-fra.com

Comment puis-je générer org.w3c.dom.Element en format de chaîne en java?

J'ai un objet org.w3c.dom.Element passé dans ma méthode. J'ai besoin de voir la chaîne XML entière, y compris ses nœuds enfants (le graphe d'objet entier). Je cherche une méthode qui peut convertir le Element en une chaîne de format XML que je peux System.out.println sur. Juste println() sur l'objet 'Element' ne fonctionnera pas car toString() ne produira pas le format XML et ne passera pas par son nœud enfant. Y at-il un moyen facile sans écrire ma propre méthode pour le faire? Merci.

83
leo

En supposant que vous souhaitiez vous en tenir à l'API standard ...

Vous pouvez utiliser un DOMImplementationLS :

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

Si la déclaration <? Xml version = "1.0" encoding = "UTF-16"?> Vous dérange, vous pouvez utiliser un transformer à la place:

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();
151
McDowell

Code simple à 4 lignes pour obtenir String sans déclaration xml (<?xml version="1.0" encoding="UTF-16"?>) à partir de 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);
14
Tarsem Singh

Si vous possédez le schéma XML ou pouvez créer des liaisons JAXB, vous pouvez utiliser le Marshaller JAXB pour écrire dans 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
wierob

Non pris en charge dans l'API JAXP standard, j'ai utilisé la bibliothèque JDom à cette fin. Il possède une fonction d’imprimante, des options de formatage, etc. http://www.jdom.org/

1
Karl

Essayez jcabi-xml avec une doublure:

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

Avec VTD-XML , vous pouvez passer au curseur et effectuer un seul appel à getElementFragment pour récupérer le segment (indiqué par son décalage et sa longueur) ... Voici un exemple

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

}
0
vtd-xml-author

voila ce que j ai fait dans 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();
}

et cela fonctionne pour moi!

0
thunderhawk