将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.Document
和org.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.Document
和nu.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();