⑴ 目前在java中几种常用的XML解析器的比较
目前常用的XML的解析器主要有:SAX,DOM,Xerces
1、SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX还比它的替代者DOM快许多。另一方面,由于应用程序没有以任何方式存储数据,使用SAX来更改数据或在数据流中往后移是不可能的。
2、DOM以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。另一方面,在内存中构造这样的树涉及大量的开销。大型文件完全占用系统内存容量的情况并不鲜见。此外,创建一棵DOM树可能是一个缓慢的过程。
3、选择DOM还是选择SAX,这取决于下面几个因素:
应用程序的目的:如果打算对数据作出更改并将它输出为XML,那么在大多数情况下,DOM是适当的选择。并不是说使用SAX就不能更改数据,但是该过程要复杂得多,因为您必须对数据的一份拷贝而不是对数据本身作出更改。
数据容量:对于大型文件,SAX是更好的选择。数据将如何使用:如果只有数据中的少量部分会被使用,那么使用SAX来将该部分数据提取到应用程序中可能更好。另一方面,如果您知道自己以后会回头引用已处理过的大量信息,那么SAX也许不是恰当的选择。
对速度的需要:SAX实现通常要比DOM实现更快。
SAX和DOM不是相互排斥的,记住这点很重要。您可以使用DOM来创建SAX事件流,也可以使用SAX来创建DOM树。事实上,用于创建DOM树的大多数解析器实际上都使用SAX来完成这个任务!
4、SAX,DOM是两种对XML文档进行分析的方法(没有具体的实现,只有接口),所以不是解释器,如果光有他们,你是完成不了对xml文档的处理的。SAX的包是org.xml.sax,DOM的包是org.w3c.dom,包的名称很重要,它有助于你理解他们之间的关系。
5、jaxp是api,他封装了sax/dom两种接口。并在sax/dom的基础之上,作了一套比较简单的api以供开发人员使用。jaxp的包是javax.xml.parsers,可以看看jaxp的源文件,它的文件中包含了对sax或者dom的引用(import)jaxp也不是具体的实现,他只是一套api。如果你仅仅有jaxp那是无法工作的,(其实jaxp只是完成对sax、dom的包装,生成了DocumentBuilderFactory/DocumentBuilder和SAXParserFactorySAXParser。也就是设计模式中的工厂模式,他的好处就是具体的对象(解释器)建立由子类完成)
6、xerces解释器(号称地球上最快的xml解释器)在xerces中对jaxp中定义的进行了继承(extends)对应ryImpl这就是为什么你的classpath中只要有xerces.jar(其中包含了saxdomjaxp)和xercesImpl.jar就可以的原因了.
⑵ java XML解析详解
(I)Java通过DOM解析XML
1>得到DOM解析器的工厂实例
DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
得到javax.xml.parsers.DocumentBuilderFactory;类的实例就是我们要的解析器工厂
2>从DOM工厂获得DOM解析器
DocumentBuilder dombuilder=domfac.newDocumentBuilder();
通过javax.xml.parsers.DocumentBuilderFactory实例的静态方法newDocumentBuilder()得到DOM解析器
3>把要解析的XML文档转化为输入流,以便DOM解析器解析它
InputStream is=new FileInputStream("bin/library.xml");
InputStream是一个接口。
4>解析XML文档的输入流,得到一个Document
Document doc=dombuilder.parse(is);
由XML文档的输入流得到一个org.w3c.dom.Document对象,以后的处理都是对Document对象进行的
5>得到XML文档的根节点
Element root=doc.getDocumentElement();
在DOM中只有根节点是一个org.w3c.dom.Element对象。
6>得到节点的子节点
NodeList books=root.getChildNodes();
for(int i=0;i<books.getLength();i++){
Node book=books.item(i);
}
这是用一个org.w3c.dom.NodeList接口来存放它所有子节点的,还有一种轮循子节点的方法,后面有介绍
7>取得节点的属性值
String email=book.getAttributes().getNamedItem("email").getNodeValue();
System.out.println(email);
注意,节点的属性也是它的子节点。它的节点类型也是Node.ELEMENT_NODE
8>轮循子节点
for(Node node=book.getFirstChild();node!=null;node=node.getNextSibling()){
if(node.getNodeType()==Node.ELEMENT_NODE){
if(node.getNodeName().equals("name")){
String name=node.getNodeValue();
String name1=node.getFirstChild().getNodeValue();
...
if(node.getNodeName().equals("price")){
String price=node.getFirstChild().getNodeValue();
...
Java通过SAX解析XML
Simple API for XML(简称SAX)是个循序存取XML的解析器API。
一个实现SAX的解析器(也就是“SAX Parser”)以一个串流解析器的型式作用,拥有事件驱动API。由使用者定义回调函数,解析时,若发生事件的话会被调用。SAX事件包括:
XML 文字 节点
XML 元素 节点
XML 处理指令
XML 注释
Java代码
<person>
<user>
<username>谢成志</username>
<password>6626310xie</password>
<sex>男</sex>
<birthday>1988/11/28</birthday>
<headpic>
<pictitle>ermao</pictitle>
<picurl>images/head1.jpg</picurl>
</headpic>
</user>
</person>
此为下面即将分辨率简单xml结构,并将其封装成一个User对象。
////////////////////////////////////////////////////////////////////////////////////
Java代码
<span style="font-family: courier new,courier; font-size: small;">package com.xcz.xml;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import com.xcz.util.SaxUtil;
public class Sax4XML {
public static void main(String[] args) {
try {
//1.获取factory
SAXParserFactory factory = SAXParserFactory.newInstance();
//2.获取parser
SAXParser parser = factory.newSAXParser();
//3.获取解析时的监听器对象
SaxUtil su = new SaxUtil();
//4.开始解析
parser.parse(new File("src/user-params.xml"), su);
System.out.println(su.getUser());
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
</span>
////////////////////////////////////////////////////////////////////////////////////
Java代码
<span style="font-family: courier new,courier; font-size: small;">package com.xcz.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.xcz.po.HeadPic;
import com.xcz.po.User;
/**
* 定义xml解析时的监听类
*
* 实现方式有很多,可以实现接口:ContentHandler,DTDHandler, EntityResolver 和 ErrorHandler
* 但我们常用的继承:DefaultHandler
*/
public class SaxUtil extends DefaultHandler {
private User user;
private HeadPic headPic;
private String content;
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
content = new String(ch, start, length);
}
//当解析到文本开始时触发
@Override
public void startDocument() throws SAXException {
super.startDocument();
}
//当解析到文本结束时触发
@Override
public void endDocument() throws SAXException {
super.endDocument();
}
//当解析到元素开始时触发
@Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException
{
if("user".equals(name))
{
user = new User();
}
if("headpic".equals(name))
{
headPic = new HeadPic();
}
}
//当解析到元素结束时触发
@Override
public void endElement(String uri, String localName, String name)
throws SAXException
{
if("username".equals(name))
{
user.setUsername(content);
}
if("password".equals(name))
{
user.setPassword(content);
}
if("sex".equals(name))
{
user.setSex(content);
}
if("birthday".equals(name))
{
try {
user.setBirthday(sdf.parse(content));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if("pictitle".equals(name))
{
headPic.setPicTitle(content);
}
if("picurl".equals(name))
{
headPic.setPicUrl(content);
user.setHeadPic(headPic);
}
}
public User getUser(){
return user;
}
}</span>
[优点]
(1).节约内存开销
SAX解析器在某些方面优于DOM风格解析器,因为SAX解析器的内存使用量一般远低于DOM解析器使用量。DOM解析器在任何处理开始之前,必须将xml以整棵树放在内存,所以DOM解析器的内存使用量完全根据输入资料的大小。相对来说,SAX解析器的内存内容,是只基于XML档案的最大深度(XML树的最大深度)和单一XML项目上XML属性储存的最大资料。
(2)解析速度快
因为SAX事件驱动的本质,处理文件通常会比DOM风格的解析器快。
[缺点]
SAX事件驱动的模型对于XML解析很有用,但它确实有某些缺点。
某些种类的XML验证需要存取整份文件。例如,一个DTD IDREF属性需要文件内有项目使用指定字串当成DTD ID属性。要在SAX解析器内验证,必须追踪每个之前遇过的ID和IDREF属性,检查是否有任何相符。更甚者,一个IDREF找不到对应的ID,使用者只会在整份文件都解析完后才发现,若这种连结对于建立有效输出是重要的,那用在处理整份文件的时间只是浪费。
⑶ 在java中解析xml有哪几种方法
1、JDOM生成和解析XML
为减少DOM、SAX的编码量,出现了JDOM
优点:20-80原则,极大减少了代键激码量。
使用场合:要实现的功能简单,如解析、创建等,但在底层,JDOM还是使用SAX(最常用)、DOM、Xanan文档。
2、SAX生成和解析XML文档
为解决DOM的问题,出现了SAX,SAX 事件驱动。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时发送事件,程序员编写响应这些事件的代码,保存数据。
优点:不用事先调入整个文档,占用资源少。SAX解析器代码比DOM解析器代码小,适于Applet下载。
缺点:不是持久的,事件过后若没保存数据,那么数据就握亮锋丢了。无状态性,从事件中只能得到文本,但不知该文本属于哪个元素。
使用场合:Applet。只段晌需XML文档的少量内容,很少回头访问,机器内存少。
3、DOM生成和解析XML文档
为XML文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 DOM 接口来操作这个树结构。
优点:整个文档树在内存中,便于操作,支持删除、修改、重新排列等多种功能。
缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间。
使用场合:一旦解析了文档还需多次访问这些数据,硬件资源充足(内存、CPU)。
4、DOM4J生成和解析XML文档
DOM4J
是一个非常非常优秀的Java XML
API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J
来读写 XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。