将String XML片段转换为Java中的文档节点

在Java中,如何将表示要插入到XML文档中的XML片段的string进行转换?

例如

String newNode = "<node>value</node>"; // Convert this to XML 

然后将这个节点插入一个org.w3c.dom.Document作为给定节点的子节点?

 Element node = DocumentBuilderFactory .newInstance() .newDocumentBuilder() .parse(new ByteArrayInputStream("<node>value</node>".getBytes())) .getDocumentElement(); 

您可以使用文档的导入 (或采用 )方法来添加XML片段:

  /** * @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); } 

为了什么是值得的,这里是我使用dom4j库的解决scheme。 (我确实检查了它的工作原理。)

将XML片段读入org.dom4j.Document (注意:下面使用的所有XML类都来自org.dom4j;请参阅附录):

  String newNode = "<node>value</node>"; // Convert this to XML SAXReader reader = new SAXReader(); Document newNodeDocument = reader.read(new StringReader(newNode)); 

然后获取插入新节点的文档以及父元素(将)。 (你的org.w3c.dom.Document需要在这里转换成org.dom4j.Document。)为了testing的目的,我创build了这样的一个:

  Document originalDoc = new SAXReader().read(new StringReader("<root><given></given></root>")); Element givenNode = originalDoc.getRootElement().element("given"); 

添加新的子元素非常简单:

  givenNode.add(newNodeDocument.getRootElement()); 

完成。 输出originalDoc现在产生:

 <?xml version="1.0" encoding="utf-8"?> <root> <given> <node>value</node> </given> </root> 

附录 :因为你的问题谈到了org.w3c.dom.Document ,下面介绍如何在org.dom4j.Documentorg.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); 

(如果你需要定期使用这两种Document ,把它们放在整洁的实用程序方法中,也许是在一个名为XMLUtils的类中,或者类似的东西,可能是XMLUtils 。)

也许有更好的方法来做到这一点,即使没有任何第三方库。 但是,到目前为止所提出的解决scheme中,我认为这是最简单的方法,即使您需要执行dom4j < – > w3c转换。

更新 (2011):在将dom4j依赖项添加到您的代码之前,请注意, 它不是一个积极维护的项目,还有其他一些问题 。 改进后的版本2.0已经在工作了很长时间,但只有一个alpha版本可用。 您可能需要考虑替代scheme,如XOM; 在上面链接的问题阅读更多。

这是另一个使用XOM库的解决scheme,与我的dom4j答案竞争。 (这是我寻求一个好的dom4j替代品的一部分 ,其中XOM被build议作为一个选项。)

首先将XML片段读入nu.xom.Document

 String newNode = "<node>value</node>"; // Convert this to XML Document newNodeDocument = new Builder().build(newNode, ""); 

然后,获取添加片段的Document和Node。 再次,为了testing目的,我将从一个string创build文档:

 Document originalDoc = new Builder().build("<root><given></given></root>", ""); Element givenNode = originalDoc.getRootElement().getFirstChildElement("given"); 

现在,添加子节点很简单,与dom4j类似(除了XOM不允许添加已经属于newNodeDocument的原始根元素):

 givenNode.appendChild(newNodeDocument.getRootElement().copy()); 

输出文档将产生正确的结果XML(对于XOM来说非常简单:仅打印由originalDoc.toXML()返回的string):

 <?xml version="1.0"?> <root><given><node>value</node></given></root> 

(如果你想很好地格式化XML(缩进和换行符),请使用Serializer ;感谢PeterŠtibraný指出了这一点。)

所以,诚然这与dom4j解决scheme并没有太大的不同。 :)但是,XOM可能会更好一点,因为API有更好的文档logging,并且由于其devise理念,每个事情都有一个规范的方法。

附录 :再次,下面是如何在org.w3c.dom.Documentnu.xom.Document之间进行转换。 在XOM的DOMConverter类中使用帮助器方法:

 // w3c -> xom Document xomDoc = DOMConverter.convert(w3cDoc); // xom -> w3c org.w3c.dom.Document w3cDoc = DOMConverter.convert(xomDoc, domImplementation); // You can get a DOMImplementation instance eg from DOMImplementationRegistry 

如果你使用的是dom4j,你可以这样做:

Document document = DocumentHelper.parseText(text);

(dom4j现在在这里find: https : //github.com/dom4j/dom4j )

 /** * * 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; } 

…如果你使用纯粹的XOM,像这样:

  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使用fakeRoot在内部做几乎相同,所以它应该是安全的,如果不是完全优雅。

尝试jcabi-xml ,一个class轮:

 Node node = new XMLDocument("<node>value</node>").node();