Wie können Sie in Java einen String konvertieren, der ein XML-Fragment zum Einfügen in ein XML-Dokument darstellt?
z.B
String newNode = "<node>value</node>"; // Convert this to XML
Fügen Sie diesen Knoten dann als untergeordnetes Element eines bestimmten Knotens in ein org.w3c.dom.Document ein.
Antworten:
Element node = DocumentBuilderFactory .newInstance() .newDocumentBuilder() .parse(new ByteArrayInputStream("<node>value</node>".getBytes())) .getDocumentElement();
quelle
Sie können die Import- (oder Adoptions- ) Methode des Dokuments verwenden, um XML-Fragmente hinzuzufügen:
/** * @param docBuilder * the parser * @param parent * node to add fragment to * @param fragment * a well formed XML fragment */ public static void appendXmlFragment( DocumentBuilder docBuilder, Node parent, String fragment) throws IOException, SAXException { Document doc = parent.getOwnerDocument(); Node fragmentNode = docBuilder.parse( new InputSource(new StringReader(fragment))) .getDocumentElement(); fragmentNode = doc.importNode(fragmentNode, true); parent.appendChild(fragmentNode); }
quelle
Hier ist eine Lösung, die ich mit dom4j gefunden habe Bibliothek gefunden habe. (Ich habe überprüft, ob es funktioniert.)
Lesen Sie das XML-Fragment in ein
org.dom4j.Document
(Hinweis: Alle unten verwendeten XML-Klassen stammen aus org.dom4j; siehe Anhang):String newNode = "<node>value</node>"; // Convert this to XML SAXReader reader = new SAXReader(); Document newNodeDocument = reader.read(new StringReader(newNode));
Holen Sie sich dann das Dokument, in das der neue Knoten eingefügt wird, und das übergeordnete Element (zu sein) daraus. (Ihr org.w3c.dom.Document müsste hier in org.dom4j.Document konvertiert werden.) Zu Testzwecken habe ich eines wie folgt erstellt:
Document originalDoc = new SAXReader().read(new StringReader("<root><given></given></root>")); Element givenNode = originalDoc.getRootElement().element("given");
Das Hinzufügen des neuen untergeordneten Elements ist sehr einfach:
givenNode.add(newNodeDocument.getRootElement());
Erledigt. Die Ausgabe
originalDoc
ergibt jetzt:<?xml version="1.0" encoding="utf-8"?> <root> <given> <node>value</node> </given> </root>
Anhang : Da es sich bei Ihrer Frage um eine Frage handelt, erfahren Sie
org.w3c.dom.Document
hier, wie Sie zwischen dieser und konvertierenorg.dom4j.Document
.// dom4j -> w3c DOMWriter writer = new DOMWriter(); org.w3c.dom.Document w3cDoc = writer.write(dom4jDoc); // w3c -> dom4j DOMReader reader = new DOMReader(); Document dom4jDoc = reader.read(w3cDoc);
(Wenn Sie beide Arten von
Document
s regelmäßig benötigen , ist es möglicherweise sinnvoll, diese in ordentliche Dienstprogrammmethoden zu integrieren, möglicherweise in eine Klasse namensXMLUtils
oder so ähnlich.)Vielleicht gibt es bessere Möglichkeiten, dies auch ohne Bibliotheken von Drittanbietern zu tun. Von den bisher vorgestellten Lösungen ist dies meiner Ansicht nach der einfachste Weg, selbst wenn Sie die dom4j <-> w3c-Konvertierungen durchführen müssen.
Update (2011): Beachten Sie vor dem Hinzufügen der dom4j-Abhängigkeit zu Ihrem Code, dass es sich nicht um ein aktiv verwaltetes Projekt handelt und auch einige andere Probleme auftreten . Die verbesserte Version 2.0 ist seit Ewigkeiten in Arbeit, es ist jedoch nur eine Alpha-Version verfügbar. Möglicherweise möchten Sie stattdessen eine Alternative wie XOM in Betracht ziehen. Lesen Sie mehr in der oben verlinkten Frage.
quelle
Hier ist noch eine andere Lösung, die die XOM- Bibliothek verwendet und mit meiner dom4j-Antwort konkurriert . (Dies ist Teil meiner Suche nach einem guten dom4j-Ersatz, bei dem XOM als eine Option vorgeschlagen wurde.)
Lesen Sie zuerst das XML-Fragment in ein
nu.xom.Document
:String newNode = "<node>value</node>"; // Convert this to XML Document newNodeDocument = new Builder().build(newNode, "");
Holen Sie sich dann das Dokument und den Knoten, unter dem das Fragment hinzugefügt wird. Zu Testzwecken erstelle ich das Dokument erneut aus einer Zeichenfolge:
Document originalDoc = new Builder().build("<root><given></given></root>", ""); Element givenNode = originalDoc.getRootElement().getFirstChildElement("given");
Das Hinzufügen des untergeordneten Knotens ist jetzt einfach und ähnlich wie bei dom4j (außer dass Sie mit XOM nicht das ursprüngliche Stammelement hinzufügen können, zu dem bereits gehört
newNodeDocument
):givenNode.appendChild(newNodeDocument.getRootElement().copy());
Die Ausgabe des Dokuments liefert das richtige Ergebnis-XML (und ist mit XOM bemerkenswert einfach: Drucken Sie einfach die von zurückgegebene Zeichenfolge aus
originalDoc.toXML()
):<?xml version="1.0"?> <root><given><node>value</node></given></root>
(Wenn Sie das XML gut formatieren möchten (mit Einrückungen und Zeilenvorschüben), verwenden Sie a
Serializer
; danke an Peter Štibraný für den Hinweis.)Zugegeben, das unterscheidet sich nicht sehr von der dom4j-Lösung. :) Es ist jedoch möglicherweise etwas besser, mit XOM zu arbeiten, da die API besser dokumentiert ist und aufgrund ihrer Designphilosophie gibt es einen kanonischen Weg, um jede Sache zu erledigen.
Anhang : Hier erfahren Sie, wie Sie zwischen
org.w3c.dom.Document
und konvertierennu.xom.Document
. Verwenden Sie die Hilfsmethoden in der XOM-DOMConverter
Klasse:// w3c -> xom Document xomDoc = DOMConverter.convert(w3cDoc); // xom -> w3c org.w3c.dom.Document w3cDoc = DOMConverter.convert(xomDoc, domImplementation); // You can get a DOMImplementation instance e.g. from DOMImplementationRegistry
quelle
/** * * Convert a string to a Document Object * * @param xml The xml to convert * @return A document Object * @throws IOException * @throws SAXException * @throws ParserConfigurationException */ public static Document string2Document(String xml) throws IOException, SAXException, ParserConfigurationException { if (xml == null) return null; return inputStream2Document(new ByteArrayInputStream(xml.getBytes())); } /** * Convert an inputStream to a Document Object * @param inputStream The inputstream to convert * @return a Document Object * @throws IOException * @throws SAXException * @throws ParserConfigurationException */ public static Document inputStream2Document(InputStream inputStream) throws IOException, SAXException, ParserConfigurationException { DocumentBuilderFactory newInstance = DocumentBuilderFactory.newInstance(); newInstance.setNamespaceAware(true); Document parse = newInstance.newDocumentBuilder().parse(inputStream); return parse; }
quelle
Wenn Sie dom4j verwenden, können Sie einfach Folgendes tun:
Dokument document = DocumentHelper.parseText (Text);
(dom4j jetzt hier zu finden: https://github.com/dom4j/dom4j )
quelle
... und wenn Sie nur XOM verwenden, so etwas:
String xml = "<fakeRoot>" + xml + "</fakeRoot>"; Document doc = new Builder( false ).build( xml, null ); Nodes children = doc.getRootElement().removeChildren(); for( int ix = 0; ix < children.size(); ix++ ) { otherDocumentElement.appendChild( children.get( ix ) ); }
XOM verwendet fakeRoot intern, um fast dasselbe zu tun. Daher sollte es sicher, wenn nicht sogar elegant sein.
quelle
Probieren Sie jcabi-xml mit einem Einzeiler aus :
Node node = new XMLDocument("<node>value</node>").node();
quelle
Unresolved references to [com.jcabi.xml] by class(es) on the Bundle-Classpath[Jar:dot]