最好的java xml解析器来操作/编辑现有的xml文档

问题描述:

任务:我有一个使用xml命名空间和xml架构的现有xml文档(UTF-8)。我需要解析一个特定的元素,将内容(也需要使用xml名称空间前缀)附加到该元素,然后再次写出文档。最好的java xml解析器来操作/编辑现有的xml文档

这是我应该用于这个任务的最好的XML解析器库吗?

我见过以前的线程(Best XML parser for Java),但不确定dom4j或JDOM对于名称空间/ xmlSchema是否有用以及对UTF-8字符的良好支持。

一些解析器这似乎是一个任务
JDOM
DOM4J
XOM
伍德斯托克

任何想法,哪一个是最好的? :-)我使用JDK 6,并且不希望使用内置的SAX/DOM工具来完成这项工作,因为这需要我编写太多的代码。

这将有助于举一些这样的任务的例子。

+0

如何做,与内置的DOM设施将是太多的代码?啊,对 - Java ... ;-)但严重:你认为15-20行代码太多了吗?那么什么可以接受? – Thomas

+0

用于繁重任务的最佳xml处理库是vtd-xml,bar none ... http://sdiwc.us/digitlib/journal_paper.php?paper=00000582.pdf –

使用JDOM,服用InputStream和使其成为一个文件:

InputStream inputStream = (InputStream)httpURLConnection.getContent(); 
DocumentBuilderFactory docbf = DocumentBuilderFactory.newInstance(); 
docbf.setNamespaceAware(true); 
DocumentBuilder docbuilder = docbf.newDocumentBuilder(); 
Document document = docbuilder.parse(inputStream, baseUrl); 

在这一点上,你有一个Java对象的XML。完成。简单。

您可以使用文档对象和Java API来浏览它,也可以使用XPath,我发现它比较容易(一旦我学会了它)。

建立一个XPath对象,这需要一个位:

public static XPath buildXPath() { 
    XPathFactory factory = XPathFactory.newInstance(); 
    XPath xpath = factory.newXPath(); 
    xpath.setNamespaceContext(new AtomNamespaceContext()); 
    return xpath; 
} 


public class AtomNamespaceContext implements NamespaceContext { 

    public String getNamespaceURI(String prefix) { 
     if (prefix == null) 
      throw new NullPointerException("Null prefix"); 
     else if ("a".equals(prefix)) 
      return "http://www.w3.org/2005/Atom"; 
     else if ("app".equals(prefix)) 
      return "http://www.w3.org/2007/app"; 
     else if ("os".equals(prefix)) 
      return "http://a9.com/-/spec/opensearch/1.1/"; 
     else if ("x".equals(prefix)) 
      return "http://www.w3.org/1999/xhtml"; 
     else if ("xml".equals(prefix)) 
      return XMLConstants.XML_NS_URI; 
     return XMLConstants.NULL_NS_URI; 
    } 

    // This method isn't necessary for XPath processing. 
    public String getPrefix(String uri) { 
     throw new UnsupportedOperationException(); 
    } 

    // This method isn't necessary for XPath processing either. 
    public Iterator getPrefixes(String uri) { 
     throw new UnsupportedOperationException(); 
    } 
} 

那么就使用它,这(谢天谢地)并不需要太多的时间都:

return Integer.parseInt(xpath.evaluate("/a:feed/os:totalResults/text()", document)); 
+0

+1 - JDOM是最容易学习的API为了这。不过,如果你经常这样做,XSLT将是更好的选择。 – jsight

使用XSLT。认真。这是一个完美的工作。只需使用复制模板即可复制所有内容,除了需要添加更多xml的位置之外。您甚至可以通过实际编写XML而不是DOM操作来添加XML。

这是复制的模板:

<xsl:template match="node() | @*"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
</xsl:template> 

我知道有很多人讨厌XSLT,但是这是一个任务,哪里会大放异彩,并采取几乎没有任何代码。另外,您可以使用JDK中的内容。

这听起来像你可以写一个xslt样式表来做你想做的。

因为写得太多代码是你的主要问题,你可能要考虑jOOX:

http://code.google.com/p/joox/

我已经创建jOOX作为jQuery到Java的端口。基础技术是Java的标准DOM。一些示例代码:

// Find the order at index for and add an element "paid" 
$(document).find("orders").children().eq(4) 
      .append("<paid>true</paid>"); 

// Find those orders that are paid and flag them as "settled" 
$(document).find("orders").children().find("paid") 
      .after("<settled>true</settled>"); 

// Add a complex element 
$(document).find("orders").append(
    $("order", $("date", "2011-08-14"), 
      $("amount", "155"), 
      $("paid", "false"), 
      $("settled", "false")).attr("id", "13"); 

注:命名空间尚未明确支持,但你可以解决这

+0

jOOX是个不错的主意。但是我失去了时间,因为这种技术不支持使用属性进行操作。没有它,这种技术只适合阅读。 – wojand

+0

@wojand:是什么让你这么想? jOOX允许对属性进行操作。请参阅我的答案中的第三个示例,其中设置了'id =“13”' –

+0

向我展示如何将属性添加到现有标记。您可以添加标签,但问题在于何时需要向现有标签添加属性。我找不到一个简单的解决方案。我在jOOX页面上找不到任何有关此问题的示例。在你的例子的append标签上添加属性,但是如何将APPEND ONLY ONE属性添加到$ {} WITHOUT标记中? – wojand