有没有更简单的方法来解析Java中的XML?

问题描述 投票:32回答:14

我正在试图弄清楚如何解析一些XML(对于一个Android应用程序),看起来很荒谬,在Java中做起来有多么困难。看起来它需要创建一个具有各种回调(startElement,endElement等)的XML处理程序,然后您必须将所有这些数据更改为对象。像this tutorial之类的东西。

我真正需要的是将XML文档更改为多维数组,更好的是使用某种Hpricot处理器。有没有办法做到这一点,或者我真的必须在上面的例子中写下所有额外的代码?

java xml android
14个回答
23
投票

Java中有两种不同类型的XML处理器(实际上有3种,但有一种很奇怪)。你有一个SAX解析器,你想要的是一个DOM解析器。看看http://www.mkyong.com/java/how-to-read-xml-file-in-java-dom-parser /如何使用DOM解析器。 DOM将创建一个您可以轻松导航的树。 SAX最适合大型文档,但如果速度较慢且内存密集程度较高,则DOM更容易。


0
投票

您还可以使用Castor将XML映射到Java bean。我以前用它,它就像一个魅力。


0
投票

SAX handler是最好的方式。一旦你这样做,你将永远不会回到别的什么。它快速,简单,随着时间的推移逐渐消失,没有吸吮大部分或上帝禁止整个DOM进入记忆。


0
投票

几个星期前,我打破了一个小型库(javax.xml.stream.XMLEventReader的包装器),允许人们以类似于手写递归下降解析器的方式解析XML。来源是available on github,下面是一个简单的用法示例。不幸的是,Android不支持此API,但它与支持的XmlPullParser API非常相似,并且移植不会太耗时。

accept("tilesets");
    while (atTag("tileset")) {
        String filename = attrib("file");
        File tilesetFile = new File(filename);
        if (!tilesetFile.isAbsolute()) {
            tilesetFile = new File(FilenameUtils.concat(file.getParent(), filename));
        }
        int tilesize = Integer.valueOf(attrib("tilesize"));
        Tileset t = new Tileset(tilesetFile, tilesize);
        t.setID(attrib("id"));
        tilesets.add(t);

        accept();
        close();
    }
close();

expect("map");

int width       = Integer.valueOf(attrib("width"));
int height      = Integer.valueOf(attrib("height"));
int tilesize    = Integer.valueOf(attrib("tilesize"));

0
投票

对于任何类型的xml,XmlPullParser都有一个非常好的示例显示。它也可以作为一种通用的方式解析,你不需要改变任何东西,只需获得该类并放入你的android项目。

Generic XmlPullParser


-3
投票

解析XML并不是一件容易的事。

它的基本结构是树,树中的任何节点都能够容纳一个由多个树组成的容器。

树中的每个节点都包含一个标记和一个值,但另外可以包含任意数量的命名属性,以及一个任意数量的子项或容器。

XML解析任务往往分为三类。

可以用“正则表达式”完成的事情。例如。您想要找到第一个“MailTo”标记的值,并且对任何其他标记的内容不感兴趣。

你可以解析自己的事情。 xml结构总是非常简单,例如根节点和具有简单值的十个众所周知的标签。

其他的!尽管xml消息格式看起来很简单,但自制的解析器很容易被额外的属性,CDATA和意外的子节点混淆。完整的XML解析器可以处理所有这些情况。这里的基本选择是在流或DOM解析器之间。如果您打算使用您想要使用它们的顺序中给出的大多数实体/属性,那么DOM解析器是理想的。如果您只对几个属性感兴趣并打算按照它们的显示顺序使用它们,那么如果您有性能限制,或者,如果xml文件很大(> 500MB),那么流式解析器就是要走的路;回调机制需要一些“groking”但实际上很容易编程一旦你得到它的挂起。


13
投票

试试http://simple.sourceforge.net,它是一个XML到Java的序列化和绑定框架,它与Android完全兼容,非常轻量级,270K并且没有依赖性。


12
投票

查看本文,了解在Android上处理XML的方法。也许DOM或XML Pull风格更适合您的风格

Working with XML on Android


3
投票

凯尔,

(请原谅这篇文章的自我推销性质...我已经在这个库上工作了好几个月,它都是开源/ Apache 2,所以不是那种自私,只是想帮助)。

我刚刚发布了一个库,我正在调用SJXP或“Simple Java XML Parser”http://www.thebuzzmedia.com/software/simple-java-xml-parser-sjxp/

它是一个非常小/紧(4类)的抽象层,位于任何符合规范的XML Pull Parser之上。

在Android和非Android Java平台上,pull解析可能是解析方法中性能最高(速度和内存开销都很低)的方法之一。不幸的是,直接针对pull-parser的编码看起来很像任何其他XML解析代码(例如SAX) - 你有异常处理程序,维护解析器状态,错误检查,事件处理,值解析等。

SJXP的功能是允许您在要从中获取值的元素或属性的文档中定义类似XPath的“路径”,例如:

/ RSS /信道/标题

当规则匹配时,它将使用值调用您的回调。 API非常简单,如果您正在尝试解析,则可以直观地支持名称空间限定的元素。

标准解析器的代码看起来像这样(解析RSS2提要标题的示例):

IRule titleRule = new DefaultRule(Type.CHARACTER, "/rss/channel/title") {
@Override
public void handleParsedCharacters(XMLParser parser, String text) {
    // Store the title in a DB or something fancy
}}

然后,您只需创建一个XMLParser实例,并为其提供您希望它关注的所有规则:

XMLParser parser = new XMLParser(titleRule);
parser.parse(xmlStream);

就是这样,解析器将在每次规则匹配时调用处理程序方法。如果需要,可以随时调用parser.stop()来停止解析。

另外(这是这个库的真正胜利)匹配的命名空间限定元素和属性很容易,您只需在括号内添加其名称空间URI,在前面添加路径中元素的名称。

举个例子,假设你想要一个RSS feed的元素,这样你就可以告诉它是什么语言(参考:http://web.resource.org/rss/1.0/modules/dc/)。您只需使用带有'dc'前缀的'language'元素的唯一命名空间URI,规则路径最终如下所示:

/RSS/channel/[HTTP://purl.org/对此/elements/1.1/]language

对于名称空间限定的属性也是如此。

尽管如此,您在解析过程中添加的唯一开销是在XML文档的每个位置进行O(1)哈希查找,并为解析器的内部位置状态提供几百字节(可能是1k)。

该库在Android上运行,没有其他依赖项(因为该平台已经提供了org.xmlpull impl),并且在任何其他Java运行时通过添加XPP3依赖项。

这个库是几个月来为每种语言编写各种feed XML的自定义pull解析器的结果,并且实现(随着时间的推移)大约90%的解析可以被提炼成这个真正基本的范例。

我希望你觉得它很方便。


2
投票

从Java 5开始,SDK中有一个XPath库。请参阅this tutorial以获取它的介绍。


2
投票

据我说,您应该使用SAX解析器,因为: - 快 - 您可以控制XML文档中的所有内容

您将花费更多时间进行编码,但这只是因为您将创建代码模板来解析XML

从第二种情况来看,您只需编辑更改内容。

祝好运!


1
投票

我已经创建了一个非常简单的API来解决这个问题。它只是一个可以包含在代码库中的类,它非常简洁,易于解析任何XML。你可以在这里找到它:

http://argonrain.wordpress.com/2009/10/27/000/


1
投票

你可以试试这个 http://xml.jcabi.com/ 它是DOM上的一个额外层,允许对XML文档和节点进行简单的解析,打印和转换


1
投票

在我看来,使用XPath for parsing XML可能是您最简单的编码方法。您可以在单个表达式中体现从XML文档中提取节点的逻辑,而不必编写代码来遍历文档的对象图。

我注意到another posted answer to this question已经建议使用XPath。但还没有适合您的Android项目。截至目前,任何Android版本都不支持XPath解析类(即使在Dalvik JVM中定义了javax.xml名称空间,这可能会欺骗你,就像我最初做的那样)。

在Android中包含XPath类是后期的当前工作项。 (正如我写的那样,它正在由Google测试和调试)。您可以在这里跟踪将XPath添加到Davlik的状态:http://code.google.com/p/android/issues/detail?id=515

(令人不安的是,你不能认为大多数Java VM支持的东西都包含在Android Dalvik VM中。)

在等待官方Google支持的另一个选择是JDOM,它目前声称Dalvik VM兼容性和XPath支持(测试版)。 (我没有检查过这个;我只是重复他们网站上的当前声明。)

© www.soinside.com 2019 - 2024. All rights reserved.