簡體   English   中英

在Java中將String XML片段轉換為Document Node

[英]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.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

如果你正在使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM