将字符串 XML 片段转换为 Java 中的文档节点

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/729621/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 18:47:05  来源:igfitidea点击:

Convert String XML fragment to Document Node in Java

javaxmlstring

提问by

In Java how can you convert a String that represents a fragment of XML for insertion into an XML document?

在 Java 中,如何转换表示 XML 片段的字符串以插入到 XML 文档中?

e.g.

例如

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

Then insert this node into an org.w3c.dom.Documentas the child of a given node?

然后将此节点作为给定节点的子节点插入到org.w3c.dom.Document中?

回答by izb

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

回答by McDowell

You can use the document's import(or adopt) method to add XML fragments:

您可以使用文档的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);
  }

回答by Jonik

For what it's worth, here's a solution I came up with using the dom4jlibrary. (I did check that it works.)

对于它的价值,这是我想出的使用dom4j库的解决方案。(我确实检查过它是否有效。)

Read the XML fragment into a org.dom4j.Document(note: all the XML classes used below are from org.dom4j; see Appendix):

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

Then get the Document into which the new node is inserted, and the parent Element (to be) from it. (Your org.w3c.dom.Document would need to be converted to org.dom4j.Document here.) For testing purposes, I created one like this:

然后获取插入新节点的文档,以及从中获取的父元素。(您的 org.w3c.dom.Document 需要在这里转换为 org.dom4j.Document。)出于测试目的,我创建了一个这样的:

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

Adding the new child element is very simple:

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

    givenNode.add(newNodeDocument.getRootElement());

Done. Outputting originalDocnow yields:

完毕。originalDoc现在输出产生:

<?xml version="1.0" encoding="utf-8"?>

<root>
    <given>
        <node>value</node>
    </given>
</root>

Appendix: Because your question talks about org.w3c.dom.Document, here's how to convert between that and org.dom4j.Document.

附录:因为您的问题涉及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);

(If you'd need both kind of Documents regularly, it might make sense to put these in neat utility methods, maybe in a class called XMLUtilsor something like that.)

(如果您Document经常需要这两种s,将它们放在整洁的实用程序方法中可能是有意义的,也许在一个名为的类XMLUtils或类似的东西中。)

Maybe there are better ways to do this, even without any 3rd party libraries. But out of the solutions presented so far, in my view this is the easiest way, even if you need to do the dom4j <-> w3c conversions.

也许有更好的方法可以做到这一点,即使没有任何 3rd 方库。但在迄今为止提出的解决方案中,我认为这是最简单的方法,即使您需要进行 dom4j <-> w3c 转换。

Update(2011): before adding dom4j dependency to your code, note that it is notan actively maintained project, and has some other problems too. Improved version 2.0 has been in the works for ages, but there's only an alpha version available. You may want to consider an alternative, like XOM, instead; read more in the question linked above.

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

回答by Jonik

Here's yet another solution, using the XOMlibrary, that competes with my dom4j answer. (This is part of my quest to find a good dom4j replacementwhere XOM was suggested as one option.)

这是另一个使用XOM库的解决方案,它与我的 dom4j answer竞争。(这是我寻找一个好的 dom4j 替代品的努力的一部分,其中 XOM 被建议作为一种选择。)

First read the XML fragment into a nu.xom.Document:

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

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

Then, get the Document and the Node under which the fragment is added. Again, for testing purposes I'll create the Document from a string:

然后,获取添加片段的文档和节点。同样,出于测试目的,我将从字符串创建文档:

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

Now, adding the child node is simple, and similar as with dom4j (except that XOM doesn't let you add the original root element which already belongs to newNodeDocument):

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

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

Outputting the document yields the correct result XML (and is remarkably easy with XOM: just print the string returned by originalDoc.toXML()):

输出文档会产生正确的结果 XML(使用 XOM 非常容易:只需打印由 返回的字符串originalDoc.toXML()):

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

(If you wanted to format the XML nicely (with indentations and linefeeds), use a Serializer; thanks to Peter ?tibrany for pointing this out.)

(如果您想很好地格式化 XML(使用缩进和换行),请使用Serializer; 感谢 Peter ?tibrany 指出这一点。)

So, admittedly this isn't very different from the dom4j solution. :) However, XOM may be a little nicer to work with, because the API is better documented, and because of its design philosophy that there's one canonical way for doing each thing.

因此,无可否认,这与 dom4j 解决方案并没有太大的不同。:) 但是,使用 XOM 可能会更好一些,因为 API 有更好的文档记录,并且因为它的设计理念是每件事都有一种规范的方式。

Appendix: Again, here's how to convert between org.w3c.dom.Documentand nu.xom.Document. Use the helper methods in XOM's DOMConverterclass:

附录:同样,这里是如何在org.w3c.dom.Document和之间转换nu.xom.Document。使用 XOMDOMConverter类中的辅助方法:

// 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

回答by ronz

If you're using dom4j, you can just do:

如果您使用的是 dom4j,则可以执行以下操作:

Document document = DocumentHelper.parseText(text);

文档文档 = DocumentHelper.parseText(text);

(dom4j now found here: https://github.com/dom4j/dom4j)

(现在可以在这里找到 dom4j:https: //github.com/dom4j/dom4j

回答by atamar

...and if you're using purely XOM, something like this:

...如果您使用的是纯 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 uses fakeRoot internally to do pretty much the same, so it should be safe, if not exactly elegant.

XOM 在内部使用 fakeRoot 来做几乎相同的事情,所以它应该是安全的,即使不是很优雅。

回答by Giordano Maestro

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

回答by yegor256

Try jcabi-xml, with a one liner:

尝试jcabi-xml,带有一个班轮:

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