[英]Convert String XML fragment to Document Node in Java
在Java中,如何将表示XML片段的String转换为XML文档?
例如
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();
您可以使用文档的import (或采用 )方法添加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库提出的解决方案。 (我确实检查过它是否有效。)
将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));
然后获取插入新节点的Document,以及从中获取父元素(将)。 (你的org.w3c.dom.Document需要在这里转换为org.dom4j.Document。)为了测试目的,我创建了一个这样的:
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
之间进行转换。
// 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
的类或类似的东西中。)
也许有更好的方法来做到这一点,即使没有任何第三方库。 但是到目前为止提供的解决方案中,在我看来这是最简单的方法,即使你需要进行dom4j < - > w3c转换。
更新 (2011):在将dom4j依赖项添加到代码之前,请注意它不是一个主动维护的项目,并且还有其他一些问题 。 改进版2.0已经开始使用多年了,但是只有alpha版本可用。 您可能想要考虑替代方案,例如XOM; 在上面链接的问题中阅读更多内容。
/**
*
* 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库的解决方案,它与我的dom4j答案竞争。 (这是我寻找一个好的dom4j替代品的一部分 ,其中XOM被建议作为一个选项。)
首先将XML片段读入nu.xom.Document
:
String newNode = "<node>value</node>"; // Convert this to XML
Document newNodeDocument = new Builder().build(newNode, "");
然后,获取文档和添加片段的节点。 同样,出于测试目的,我将从字符串创建Document:
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()
返回的字符串):
<?xml version="1.0"?>
<root><given><node>value</node></given></root>
(如果你想很好地格式化XML(使用缩进和换行符),请使用Serializer
;感谢PeterŠtibraný指出这一点。)
所以,诚然,这与dom4j解决方案没有太大区别。 :)然而,XOM可能会更好一些,因为API更好地记录,并且由于其设计理念,有一种规范的方式来做每件事。
附录 :同样,这里是如何在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 e.g. from DOMImplementationRegistry
如果你正在使用dom4j,你可以这样做:
Document document = DocumentHelper.parseText(text);
(dom4j现在在这里找到: https : //github.com/dom4j/dom4j )
试试jcabi-xml ,一个内衬:
Node node = new XMLDocument("<node>value</node>").node();
...如果你使用的是纯粹的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几乎一样,所以它应该是安全的,如果不是很优雅的话。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.