1.SAX解析
解析方式是事件驱动机制!
SAX解析器,逐行读取XML文件解析,每当解析到一个标签的开始/结束/内容/属性时,触发事件。
可以在这些事件发生时,编写程序进行相应的处理。
优点:
分析能够立即开始,而不是等待所有的数据被处理。
逐行加载,节省内存,有助于解析大于系统内存的文档。
有时不必解析整个文档,它可以在某个条件得到满足时停止解析。
缺点:
1.单向解析,无法定位文档层次,无法同时访问同一个文档的不同部分数据(因为逐行解析,当解析第n行时,第n-1行)已经被释放了,无法再对其进行 *** 作)。
2. 无法得知事件发生时元素的层次, 只能自己维护节点的父/子关系。
3. 只读解析方式, 无法修改XML文档的内容。
2. DOM解析
是用与平台和语言无关的方式表示XML文档的官方W3C标准,分析该结构通常需要加载整个 文档和内存中建立文档树模型。程序员可以通过 *** 作文档树, 来完成数据的获取 修改 删除等。
优点:
文档在内存中加载, 允许对数据和结构做出更改。访问是双向的,可以在任何时候在树中双向解析数据。
缺点:
文档全部加载在内存中 , 消耗资源大。
3. JDOM解析
目的是成为Java特定文档模型,它简化与XML的交互并且比使用DOM实现更快。由于是第一 个Java特定模型,JDOM一直得到大力推广和促进。
JDOM文档声明其目的是“使用20%(或更少)的精力解决80%(或更多)Java/XML问题” (根据学习曲线假定为20%)
优点:
使用具体类而不是接口,简化了DOM的API。
大量使用了Java集合类,方便了Java开发人员。
缺点:
没有较好的灵活性。
性能不是那么优异。
4. DOM4J解析
它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能,包括集成的XPath 支持、XML Schema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项, DOM4J是一个非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一 个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML。
目前许多开源项目中大量采用DOM4J , 例如:Hibernate。
其实解析xml有两种方式,一种叫dom,一种就是sax。其中dom的解析方式是一次性把xml读入到内存中,然后按照xml的结构在内存中生成一颗dom树,这样你可以从xml的根节点开始访问xml的每一个节点。但是种方式因为要把xml一次性全部读入内存,所以内存的消耗是很大的。如果xml很大的话,不建议使用这种方式。
sax比较灵活,它是一个标签,一个标签的解析,每解析一个标签的时候就会调用相应的一个函数。已经解析过的标签,就被程序丢掉了(除非用你自己的方式把它记下来)。给你举个例子,比如有这样一个xml文件:
<年级
名称=“一年级”>
<班级
名称=“一班”>
<班主任
名称=“xxx”/>
班级
<班级
名称=“二班”>
<班主任
姓名=“yyy”>
班级
年级
对于这个xml,sax的解析方式是,首先遇到"年级"标签,然后调用函数startelement(),在这个方法里,你可以读取“年级”标签的名称是“一年级”,然后往下执行,读到了班级,这个时候程序会再次自动的触发startelement()方法,然后得到班级的名称,这个时候已经读取的“年级”的信息就不存在了。后面的标签以此类推。
当读到
班级
标签的时候,程序会自动出发endelement()方法。当然读到
年级
的时候也会触发这个方法。
总的来说,程序对xml每做一次进一步的 *** 作,就会触发一个相应的函数,触发的这个函数叫做回调函数(其实不知道它是回调函数也没关系)。个人感觉整个解析的过程就类似于对栈的 *** 作。
解释的很粗浅,因为如果真正要把这个问题说明白很麻烦,不过希望这个解释能给你帮助
:)
请参考
//////////////////////////////////////////////////// /// 说明 : 解析XML文件 返回XML的根节点 /// 参数 : /// : xml xml文件路径 [in] /// : buffer 供解析用的缓冲 [in] /// : buffer_len 缓冲大小(单位:字节) [in] /// : error_reason 执行出错时保存错误原因 [in] /// : root XML的根节点 [out] /// 返回 : 成功 返回 失败返回 /// 说明 : /// : 问 :供解析用的缓冲应该取多大比较合适呢? /// : 答 :供解析用的缓冲主要用来存放XML树 所以 buffer_len >= (XML文件的大小) * 即可 /// :
int mini_parse_xml (char* xml char* buffer int buffer_len char error_reason[ ] MINI_XML_NODE** root)
//////////////////////////////////////////////////// /// 说明 : 查找特定节点的子节点 /// 参数 : /// : father 父结点 [in] /// : name 子孩子节点名 [in] /// : child 子节点 [out]
int mini_find_child (MINI_XML_NODE* father char* name MINI_XML_NODE** child)
//////////////////////////////////////////////////// /// 说明 : 查找特定节点的属性值 /// 参数 : /// : node 节点 [in] /// : name 属性名 [in] /// : value 属性值 [out]
int mini_find_attribute (MINI_XML_NODE* node char* name char** value)
//////////////////////////////////////////////////// /// 说明 : 打印XML树 供调试用 int mini_print_tree (MINI_XML_NODE* root int layer)
#if defined (__cplusplus) || defined (c_plusplus) } #endif #endif
lishixinzhi/Article/program/net/201311/14908
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)