Java XML解析器
使用Apache Xerces解析XML文档
一、技术概述
在用Java解析XML时候,一般都使用现成XML解析器来完成,自己编码解析是一件很棘手的问题,对程序员要求很高,一般也没有专业厂商或者开源组织实现的好。
Java解析XML的原理图如下:
目前Java XML解析器有十多种之多,解析原理有二:使用基于事件的XML简单API(Simple API for XML)称为SAX和基于树和节点的文档对象模型(Document Object Module)称为DOM。Sun公司提供了Java API for XML Parsing(JAXP)接口来使用SAX和DOM,通过JAXP,我们可以使用任何与JAXP兼容的XML解析器。但并不是所有的Java XML解析工具都实现了SUN提供的接口。DOM4J就没有遵循SUN的JAXP规范,但非常优秀。
DOM 采用建立树形结构的方式访问 XML 文档,而 SAX 采用的事件模型。
DOM 是W3C组织推荐的处理XML的标准接口,DOM 解析器把 XML 文档转化为一个包含其内容的树,并可以对树进行遍历。用 DOM 解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用 DOM 解析器的时候需要处理整个 XML 文档,所以对性能和内存的要求比较高,尤其是遇到很大的 XML 文件的时候。由于它的遍历能力,DOM 解析器常用于 XML 文档需要频繁的改变的服务中。
SAX是由XML_DEV邮件列表的成员开发的,它不是某个官方机构的标准,也不由W3C组织或其他任何官方机构维护,但它是XML社区事实上的标准。虽然SAX只是“民间”标准,但是它在XML中的应用丝毫不比DOM少,几乎所有的XML解析器都支持它。SAX 解析器采用了基于事件的模型,它在解析 XML 文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX 对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag。特别是当开发人员只需要处理文档中所包含的部分数据时,SAX 这种扩展能力得到了更好的体现。但用 SAX 解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。
DOM和SAX只是定义了一些接口,以及某些接口的默认实现,一个应用程序要想利用DOM或SAX访问XML文档,还需要一个实现了DOM或SAX的解析器(实现DOM和SAX中定义的接口,提供DOM和SAX定义的功能)。
Apache的Xerces是一个使用非常广泛的解析其,它提供了DOM和SAX的调用接口,并有多种语言的实现版本,要利用Xerces访问XML文档,只需要在应用程序中构造一个解析器实现类的对象。
这里面还存在一个问题,虽然使用的是标准的DOM和SAX接口,由于不同的XML解析器的实现类是不同的,如果使用另外一种解析器,仍然需要修改应用程序,只不过修改的代码量较小,需要更改XML解析器实现类的类名,然后重新编译、发布。
然而,对于兼容JAXP的XML解析器,我们可以选用JAXP API,这样在更换兼容JAXP解析器的时候,就不用对已发布的程序做任何的改动。
JAXP开发包由javax.xml包、org.w3c.dom包、org.xml.sax包及其子包组成。在javax.xml.parsers包中,定义了几个工厂类,用于加载DOM和SAX的实现类。
使用JAXP API解析XML的原理如下:
二、使用DOM解析XML
DOM的核心概念就是NODE(节点)。DOM在分析XML文档时,将组成XML文档的各个部分(元素,属性,文本,注释,处理指令等)映射成一个对象,这个对象就叫做节点。在内存中这些节点形成一棵树。整棵树就是一个节点,树中的每一个节点也是一棵树(子树)。DOM就是对这棵树的一个对象描述,我们通过访问树中的节点来存取XML文档的内容。
DOM定义了一个Node接口,用于表示文档树中一个节点。从这个接口派生出来更多的具体的接口。例如,表示整个文档的Document接口,表示XML文档中的一个元素的Element接口,表示元素属性的Attr接口,都是从Node接口派生而来的。在org.w3c.dom包中,表示XML文档各组成部分的接口的继承关系如图:
举个例子,引用java web开发大全,有改动:
students.xml
----------------------------------------------------------------------
<?xml version="1.0" encoding="GB2312"?>
<?xml-stylesheet type="text/xsl" href="students.xsl"?>
<students>
<student sn="01">
<name>张三</name>
<age>18</age>
</student>
<student sn="02">
<name>李四</name>
<age>20</age>
</student>
</students>
----------------------------------------------------------------------
public class DOMStudentsInfo {
public static void main(String[] args) {
//获取生成 DOM 对象树的解析器
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
//从 DocumentBuilderFactory获取 DocumentBuilder实例
DocumentBuilder db = dbf.newDocumentBuilder();
File file = new File("students.xml");
////从 XML 文档获取 DOM 文档实例
Document doc = db.parse(file);
//获取某节点的集合
NodeList nl = doc.getElementsByTagName("student");
int len = nl.getLength();
for (int i = 0; i < len; i++) {
Element eltStu = (Element) nl.item(i);
Node eltName = eltStu.getElementsByTagName("name").item(0);
Node eltAge = eltStu.getElementsByTagName("age").item(0);
String name = eltName.getFirstChild().getNodeValue();
String age = eltAge.getFirstChild().getNodeValue();
System.out.print("姓名:");
System.out.println(name);
System.out.print("年龄:");
System.out.println(age);
System.out.println("----------------------------\n");
}
}
catch (ParserConfigurationException e) {
e.printStackTrace();
}
catch (SAXException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果:
姓名:张三
年龄:18
----------------------------
姓名:李四
年龄:20
----------------------------
Process finished with exit code 0
关于Node接口的更多信息,可以参看JDK的API文档。
三、使用SAX解析XML
data_10k.xml
----------------------------------------------------------------------
<?xml version="1.0" encoding="GB2312"?>
<?xml-stylesheet type="text/xsl" href="students.xsl"?>
<result>
<value>
<no>a1234</no>
<addr>四川省xx县xx镇xx路x段xx号</addr>
</value>
<value>
<no>b1234</no>
<addr>四川省xx市xx乡xx村xx组</addr>
</value>
</result>
----------------------------------------------------------------------
public class MyXMLReader2 extends DefaultHandler {
java.util.Stack tags = new java.util.Stack();
public MyXMLReader2() {
super();
}
public static void main(String args[]) {
long lasting = System.currentTimeMillis();
try {
SAXParserFactory sf = SAXParserFactory.newInstance();
SAXParser sp = sf.newSAXParser();
MyXMLReader2 reader = new MyXMLReader2();
sp.parse(new InputSource("data_10k.xml"), reader);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("运行时间:" + (System.currentTimeMillis() - lasting) + " 毫秒");
}
public void characters(char ch[], int start, int length) throws SAXException {
String tag = (String) tags.peek();
if (tag.equals("no")) {
System.out.print("车牌号码:" + new String(ch, start, length));
}
if (tag.equals("addr")) {
System.out.println(" 地址:" + new String(ch, start, length));
}
}
public void startElement(
String uri,
String localName,
String qName,
Attributes attrs) {
tags.push(qName);
}
}
运行结果:
车牌号码:a1234车牌号码:
地址:四川省xx县xx镇xx路x段xx号
地址:
地址:
车牌号码:b1234车牌号码:
地址:四川省xx市xx乡xx村xx组
地址:
地址:
运行时间:327 毫秒
Process finished with exit code 0
四、使用DOM4j解析xml
public class MyXMLReader4 {
public static void main(String arge[]) {
long lasting = System.currentTimeMillis();
try {
File f = new File("data_10k.xml");
SAXReader reader = new SAXReader();
Document doc = reader.read(f);
Element root = doc.getRootElement();
Element foo;
for (Iterator i = root.elementIterator("value"); i.hasNext();) {
foo = (Element) i.next();
System.out.print("车牌号码:" + foo.elementText("no"));
System.out.println(" 车主地址:" + foo.elementText("addr"));
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("运行时间:" + (System.currentTimeMillis() - lasting) + " 毫秒");
}
}
五、使用JDOM解析xml
public class MyXMLReader3 {
public static void main(String arge[]) {
long lasting = System.currentTimeMillis();
try {
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(new File("data_10k.xml"));
Element foo = doc.getRootElement();
List allChildren = foo.getChildren();
for (int i = 0; i < allChildren.size(); i++) {
System.out.print("车牌号码:" + ((Element) allChildren.get(i)).getChild("no").getText());
System.out.println(" 车主地址:" + ((Element) allChildren.get(i)).getChild("addr").getText());
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("运行时间:" + (System.currentTimeMillis() - lasting) + " 毫秒");
}
}
六、使用JAXP解析XML
public class MyXMLReader1 {
public static void main(String arge[]) {
long lasting = System.currentTimeMillis();
try {
File f = new File("data_10k.xml");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(f);
NodeList nl = doc.getElementsByTagName("value");
for (int i = 0; i < nl.getLength(); i++) {
System.out.print("车牌号码:" + doc.getElementsByTagName("no").item(i).getFirstChild().getNodeValue());
System.out.println(" 车主地址:" + doc.getElementsByTagName("addr").item(i).getFirstChild().getNodeValue());
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("运行时间:" + (System.currentTimeMillis() - lasting) + " 毫秒");
}
}
Java XML解析器的更多相关文章
- 使用java自带的xml解析器解析xml
使用java自带的xml解析器解析xml,其实我不推荐,可以用Dom解析,或其他的方式,因为Java自带的解析器使用不但麻烦,且还有bug出现. 它要求,针对不同的xml(结构不同),必须写对应的ha ...
- tinyxml一个优秀的C++ XML解析器
读取和设置xml配置文件是最常用的操作,试用了几个C++的XML解析器,个人感觉TinyXML是使用起来最舒服的,因为它的API接口和Java的十分类似,面向对象性很好. TinyXML是一个开源的解 ...
- TinyXML:一个优秀的C++ XML解析器
//-------------------------------------------------------------------------------------------------- ...
- 转:TinyXM--优秀的C++ XML解析器
读取和设置xml配置文件是最常用的操作,试用了几个C++的XML解析器,个人感觉TinyXML是使用起来最舒服的,因为它的API接口和Java的十分类似,面向对象性很好. TinyXML是一个开源的解 ...
- XML解析器(转)
常见C/C++ XML解析器有tinyxml.XERCES.squashxml.xmlite.pugxml.libxml等等,这些解析器有些是支持多语言的,有些只是单纯C/C++的.如果你是第一次接触 ...
- XML 解析器
所有现代浏览器都内建了供读取和操作 XML 的 XML 解析器.解析器把 XML 转换为 XML DOM 对象 - 可通过 JavaScript 操作的对象. 解析 XML 文档为DOM对象 方法一: ...
- TinyXML:一个优秀的C++ XML解析器[转]
TinyXML:一个优秀的C++ XML解析器 读取和设置xml配置文件是最常用的操作,试用了几个C++的XML解析器,个人感觉TinyXML是使用起来最舒服的,因为它的API接口和Java的十分类似 ...
- XML概念定义以及如何定义xml文件编写约束条件java解析xml DTD XML Schema JAXP java xml解析 dom4j 解析 xpath dom sax
本文主要涉及:xml概念描述,xml的约束文件,dtd,xsd文件的定义使用,如何在xml中引用xsd文件,如何使用java解析xml,解析xml方式dom sax,dom4j解析xml文件 XML来 ...
- JavaScript使用浏览器内置XML解析器解析DOM对象
所有现代浏览器都内建了供读取和操作 XML 的 XML 解析器.解析器把 XML 转换为 XML DOM 对象 (可通过 JavaScript 操作的对象). 一.获取DOM对象 XMLHttpReq ...
随机推荐
- PAT乙1001
我脑洞大了..... 以为是个找规律..... 原来只是模拟..... 我相信肯定是有规律的..... 但是我就是不愿意了..... #include<cstdio> #include&l ...
- SpringMVC中获得HttpRequest对象的方法
1. 使用@autowired注入HttpRequest 2. 在方法中直接声明形参有HttpRequest即可. 3. 使用一个Listener,然后获取.
- Servlet程序开发--实例操作:MVC设计模式应用
以前做过一个登录程序,是用JSP+JavaBean完成的,最大的问题,JSP文件内容太多了. 1. VO 2. DBC 3. DAO 3.1 impl 3.2 proxy 4. Factory 5. ...
- Redis 密码设置和登录
Redis 一般在生产环境中,大家都不使用密码,为了确保安全,都是在防火墙上对redis端口做IP白名单的 我是个技术控,我非得了解一下密码这回事[虽然以后不会用到,呵呵] 好了,废话不多说,简单介绍 ...
- Android开发之InstanceState详解(转)---利用其保存Activity状态
Android开发之InstanceState详解 本文介绍Android中关于Activity的两个神秘方法:onSaveInstanceState() 和 onRestoreInstanceS ...
- phpstorm 格式化代码方法
hpstorm 代码格式化方法: 快捷键:Ctrl + Alt + L 设置代码样式:File -> Settings -> Code Style ->PHP 根据个人php代码规范 ...
- VS2015安装提示出现“安装包丢失或损坏”解决方法
原因:microsoft root certificate authority 2010.microsoft root certificate authority 2011证书未安装,导致文件校验未通 ...
- 关于css3的calc()
么是calc()? 学习calc()之前,我们有必要先知道calc()是什么?只有知道了他是个什么东东?在实际运用中更好的使用他. calc()从字面我们可以把他理解为一个函数function.其实c ...
- Cow Rectangles
Cow Rectangles 题目描述 The locations of Farmer John's N cows (1 <= N <= 500) are described by dis ...
- [iOS]C语言技术视频-06-程序循环结构(for{})
下载地址: 链接: http://pan.baidu.com/s/1dD11Zwt 密码: rke9