用于操作/编辑现有 xml 文档的最佳 java Xml 解析器

Posted

技术标签:

【中文标题】用于操作/编辑现有 xml 文档的最佳 java Xml 解析器【英文标题】:best java Xml parser to manipulate/edit an existing xml document 【发布时间】:2011-02-01 04:14:11 【问题描述】:

任务:我有一个现有的 xml 文档 (UTF-8),它使用 xml 命名空间和 xml 模式。我需要解析到特定元素,将内容(也需要使用 xml 命名空间前缀)附加到该元素,然后再次写出 Document。

我应该为这个任务使用哪个最好的 XML 解析器库?

我看过之前的帖子 (Best XML parser for Java),但不确定 dom4j 或 JDOM 是否适用于命名空间/xmlSchema 以及对 UTF-8 字符的良好支持。

一些解析器似乎是一项任务 JDom Dom4J XOM 伍德斯托克

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

提供一些执行此类任务的示例会有所帮助。

【问题讨论】:

如何使用内置的 DOM 工具来编写代码?啊,对 - Java... ;-) 但说真的:在您看来,15-20 行代码太多了吗?那么什么是可以接受的呢? 【参考方案1】:

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

这是复制模板:

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

我知道很多人讨厌 XSLT,但这是一项非常出色且几乎不需要代码的任务。此外,您可以只使用 JDK 中的内容。

【讨论】:

【参考方案2】:

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

【讨论】:

【参考方案3】:

使用 JDOM,获取 InputStream 并使其成为 Document:

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

【讨论】:

+1 - JDOM 是最容易学习的 API。不过,如果您经常执行此类任务,XSLT 将是更好的选择。【参考方案4】:

由于编写太多代码是您的主要问题,您可能需要考虑 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");

注意:尚未明确支持命名空间,但您可以解决此问题

【讨论】:

jOOX 是个好主意。但是我浪费了时间,因为这项技术不支持使用属性进行操作。没有它,这项技术只适合阅读。 @wojand:是什么让你这么认为? jOOX 允许对属性进行操作。请参阅我的答案中的第三个示例,它设置了id="13" 向我展示如何向现有标签添加属性。您可以添加标签,但问题是何时需要向现有标签添加属性。我找不到简单的解决方案。我在 jOOX 页面上没有找到任何关于这个问题的例子。在您的示例上方附加带有属性的标签,但是如何只将一个属性附加到 $ 而没有标签? 我不确定我是否理解。只能给元素添加属性,为什么要给“空”的东西添加属性? @gaurav:它只是包装了org.w3c.dom,因此继承了DOM的线程不安全性。

以上是关于用于操作/编辑现有 xml 文档的最佳 java Xml 解析器的主要内容,如果未能解决你的问题,请参考以下文章

Java 将 XML 文档附加到现有文档

在 Java 中解析各种自定义 XML 文档的最佳方法

在 Java 项目中,用于数据字典的文件格式将提供最佳性能? [关闭]

UIWebView 能否用于在 iOS 应用中查看和编辑 XML 文档

在现有文档中编辑 Range NumberFormat

数千个文档(pdf 和/或 xml)的可搜索存档的最佳实践