我正在试图弄清楚如何解析一些XML(对于一个Android应用程序),看起来很荒谬在Java中做起来有多么困难。看起来它需要创建一个具有各种回调(startElement,endElement等)的XML处理程序,然后您必须将所有这些数据更改为对象。类似于this tutorial。
我真正需要的是将XML文档更改为多维数组,更好的是拥有某种Hpricot处理器。有没有办法做到这一点,或者我真的必须在上面的例子中写下所有额外的代码吗?
答案 0 :(得分:23)
Java中有两种不同类型的XML处理器(实际上有3种,但有一种很奇怪)。你有一个SAX解析器,你想要的是一个DOM解析器。查看http://www.mkyong.com/java/how-to-read-xml-file-in-java-dom-parser /了解如何使用DOM解析器。 DOM将创建一个您可以轻松导航的树。 SAX最适合大型文档,但如果速度较慢且内存密集程度较高,则DOM更容易。
答案 1 :(得分:13)
尝试http://simple.sourceforge.net,它是一个XML到Java的序列化和绑定框架,它与Android完全兼容,非常轻量级,270K,没有依赖。
答案 2 :(得分:12)
查看本文,了解在Android上处理XML的方法。也许DOM或XML Pull风格更适合您的风格
答案 3 :(得分:3)
凯尔,
(请原谅这篇文章的自我推销性质...我已经在这个库上工作了好几个月,而且它都是开源的/ Apache 2,所以不是那种自助服务,只是想提供帮助)。 / p>
我刚刚发布了一个我正在调用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提要的元素,这样您就可以知道它所使用的语言(参考:http://web.resource.org/rss/1.0/modules/dc/)。您只需使用带有'dc'前缀的'language'元素的唯一命名空间URI,规则路径最终如下所示:
/ RSS /信道/ [http://purl.org/dc/elements/1.1/]语言
同样适用于名称空间限定的属性。
尽管如此,您在解析过程中添加的唯一开销是在XML文档的每个位置进行O(1)哈希查找,并为解析器的内部位置状态提供几百字节(可能是1k)
该库在Android上运行,没有其他依赖项(因为该平台已经提供了org.xmlpull impl),并且通过添加XPP3依赖项在任何其他Java运行时中运行。
这个库是几个月来为每种语言编写各种feed XML的自定义pull解析器的结果,并且(随着时间的推移)实现了大约90%的解析可以被提炼成这个真正基本的范例。 / p>
我希望你觉得它很方便。
答案 4 :(得分:2)
从Java 5开始,SDK中有一个XPath库。有关它的介绍,请参阅this tutorial。
答案 5 :(得分:2)
根据我的说法,你应该使用SAX解析器,因为: - 快 - 您可以控制XML文档中的所有内容
您将花费更多时间进行编码,但这只是因为您将创建代码模板来解析XML
从第二种情况来看,您只需编辑更改内容。
祝你好运!答案 6 :(得分:1)
在我看来,使用XPath for parsing XML可能是最简单的编码方法。您可以在单个表达式中体现从XML文档中提取节点的逻辑,而不必编写代码来遍历文档的对象图。
我注意到another posted answer to this question已经建议使用XPath。 但尚未针对您的Android项目。截至目前, XPath解析类在任何Android版本中都不支持(即使在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支持(测试版)。 (我没有检查过这个;我只是在他们的网站上重复当前的声明。)
答案 7 :(得分:1)
我已经创建了一个非常简单的API来解决这个问题。它只是一个可以包含在代码库中的类,它非常简洁,易于解析任何XML。你可以在这里找到它:
答案 8 :(得分:1)
You can try this
http://xml.jcabi.com/
It is is an extra layer on top of DOM that allows simple parsing, printing, and transforming of XML documents and nodes
答案 9 :(得分:0)
您还可以使用Castor将XML映射到Java bean。我之前使用它,它就像一个魅力。
答案 10 :(得分:0)
写SAX handler
是最好的方法。一旦你这样做,你将永远不会回到别的什么。它快速,简单,随着时间的推移逐渐消失,没有吸吮大部分或上帝禁止整个DOM进入记忆。
答案 11 :(得分: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"));
答案 12 :(得分:0)
对于任何类型的xml,XmlPullParser都有一个很好的示例。它也可以作为一种通用的方式解析,你不需要改变任何东西,只需获得该类并放入你的android项目。
答案 13 :(得分:-3)
解析XML并不是一件容易的事。
它的基本结构是一棵树,树中的任何节点都能够容纳一个由多个树组成的容器。
树中的每个节点都包含一个标记和一个值,但另外可以包含一个任意数量的命名属性,以及一个子句数量的子项或容器。
XML解析任务往往属于三个类别。
“正则表达式”可以完成的事情。例如。你想找到第一个“MailTo”标签的价值,并且对任何其他标签的内容不感兴趣。
你可以自己解析的事情。 xml结构总是非常简单,例如根节点和十个众所周知的具有简单值的标签。
其余的一切!尽管xml消息格式看起来很简单,但自制的解析器很容易被额外的属性,CDATA和意外的子节点混淆。完整的XML解析器可以处理所有这些情况。这里的基本选择是在流或DOM解析器之间。如果您打算使用您想要使用它们的顺序中给出的大多数实体/属性,那么DOM解析器是理想的。如果您只对几个属性感兴趣并打算按照它们的显示顺序使用它们,如果您有性能限制,或者,如果xml文件很大(> 500MB),那么流式解析器就是要走的路;回调机制需要一些“groking”但实际上很容易编程一旦你得到它的挂起。