在Java中将String XML片段转换为Document Node

72 java xml string

在Java中,如何将表示XML片段的String转换为XML文档?

例如

String newNode =  "<node>value</node>"; // Convert this to XML
Run Code Online (Sandbox Code Playgroud)

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

izb*_*izb 60

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

  • 我只是讨厌这些评论框和他们没有标记(或者降价,就此而言) (5认同)
  • 但是这并没有复制孩子......例如,如果你在"<tag1> <tag2> <tag3> blah </ tag3> blah </ tag2> </ tag1>的情况下这样做,它只获得<tag1>它的孩子 (4认同)
  • .parse(new StringInputStream(....应该读取.parse(new ByteArrayInputStream(new String("xml").getBytes())); (3认同)

McD*_*ell 33

您可以使用文档的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);
  }
Run Code Online (Sandbox Code Playgroud)

  • 嗯.如果这是最简单的解决方案,我必须说这对于这么小的问题来说相当复杂. (5认同)
  • 这正是我想要的.我没有意识到我必须将片段导入dom,然后才将其附加到父节点! (3认同)

Jon*_*nik 14

对于它的价值,这是我使用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));
Run Code Online (Sandbox Code Playgroud)

然后获取插入新节点的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");
Run Code Online (Sandbox Code Playgroud)

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

    givenNode.add(newNodeDocument.getRootElement());
Run Code Online (Sandbox Code Playgroud)

完成.originalDoc现在输出产量:

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

<root>
    <given>
        <node>value</node>
    </given>
</root>
Run Code Online (Sandbox Code Playgroud)

附录:因为你的问题在谈论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);
Run Code Online (Sandbox Code Playgroud)

(如果你需要Document经常使用这两种方法,那么将它们放在整齐的实用程序方法中可能是有意义的,可能在一个叫做类XMLUtils或类似的类中.)

也许有更好的方法来做到这一点,即使没有任何第三方库.但是到目前为止提供的解决方案中,在我看来这是最简单的方法,即使你需要进行dom4j < - > w3c转换.

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


Jon*_*nik 6

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

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

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

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

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

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

givenNode.appendChild(newNodeDocument.getRootElement().copy());
Run Code Online (Sandbox Code Playgroud)

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

<?xml version="1.0"?>
<root><given><node>value</node></given></root>
Run Code Online (Sandbox Code Playgroud)

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

所以,诚然,这与dom4j解决方案没有太大区别.:)然而,XOM可能会更好一些,因为API更好地记录,并且由于其设计理念,有一种规范的方式来做每件事.

附录:再次,这里是如何转换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 e.g. from DOMImplementationRegistry
Run Code Online (Sandbox Code Playgroud)


Gio*_*tro 6

/**
*
* 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;
}
Run Code Online (Sandbox Code Playgroud)


小智 5

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

文档 document = DocumentHelper.parseText(text);

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

  • 显然,该网站不再由 dom4j 人员运营,但一些域名抢夺者接管了...... (2认同)