在JAVA中,解析有三种方式:

  • Dom解析(支持改删,耗内存)、
  • Sax解析(不支持改删,不耗内存)、
  • Pull解析(在Android中推荐使用的一种解析XML的方式,在下章18.JAVA-pull解析XML学习)

1.支持Dom与Sax解析的开发包

分为两种.

  • JAXP:  由sun公司推出的解析标准实现(本章只学习该包的解析方法)
  • Dom4j:  一种开源的解析开发包.

jaxp是java api中自带的一个包,而dom4j需要我们加入jar文件才能使用

2.JAXP使用

JAXP(Java API for XMLProcessing)主要由下面几个包组成:

  • org.w3c.dom: 定义DOM解析器的标准接口
  • org.w3c.sax: 定义SAX解析器的标准接口
  • javax.xml:提供解析xml文档的类
  • javax.xml.parsers:提供了用来获取DOM和SAX解析器对象的工厂类,比如:DocumentBuilderFactory(创建DOM解析器对象)、SAXParserFactory,如下图所示:

3.使用JAXP进行DOM解析

会将XML文档全部内容都读入内存中,并且将文档里的每个数据都创建为一个个对象,所以方便增删改.并且遍历简单。

DOM的缺点主要表现在:效率低,解析速度慢,内存占用量过高,对于大文件来说几乎不可能使用。

3.1 persons.xml示例如下:

<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person>
<姓名>张三</姓名>
<性别>男</性别>
<年龄>22</年龄>
</person> <person>
<姓名>李四</姓名>
<性别>男</性别>
<年龄>17</年龄>
</person>
</persons>

3.2 DOM读取xml步骤

1.通过DocumentBuilderFactory.newInstance()静态方法得到创建 DOM 解析器的工厂对象(DocumentBuilderFactory)

2.通过工厂对象的newDocumentBuilder()方法得到 DocumentBuilder解析器对象

3.然后通过DocumentBuilder解析器对象的parse(filename)方法来得到解析xml文档的Document对象

4.通过Document对象的成员方法来获取XML文档的元素信息,比如getElementsByTagName("person")方法来获取xml文件中的person元素(返回的类为NodeList,保存person所有的集合,比如list.item(0). getTextContent()打印第一个元素的内容)

具体实现方法如下:

@Test
public void DomReadXml() throws Exception{ //获取工厂实例
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
//创建builder
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
//解析xml
Document document = documentBuilder.parse("src//persons.xml");
//读出元素内容
System.out.println("第一个姓名:"+document.getElementsByTagName("姓名").item(0).getTextContent());
//读出元素内容
System.out.println("第二个姓名:"+document.getElementsByTagName("姓名").item(1).getTextContent()); }

打印:

3.3 DOM修改xml步骤

1.先将xml信息读取到Document对象

2.然后通过getElementsByTagName("person")方法来获取xml文件中的person元素(返回的类为NodeList),然后通过NodeList.item(i).setTextContent("text")来修改节点内容

3.修改完成后通过Transformer类的transform(Source , Result )方法来将改过的Document对象写入XML文件

具体实现方法如下:

  @Test

    public void DomWriteXml() throws Exception{
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
//1.先将xml信息读取到Document对象中
Document document = documentBuilder.parse("src//persons.xml"); //2.修改第一个节点内容为99
document.getElementsByTagName("年龄").item(0).setTextContent("99"); //3.通过transform(Source , Result )方法来将改过的Document对象写入XML文件
Transformer transformer = TransformerFactory.newInstance().newTransformer();
Source xmlSource = new DOMSource(document);
Result outputTarget = new StreamResult("src//persons.xml");
transformer.transform(xmlSource, outputTarget);
}

4.使用JAXP进行SAX解析

sax解析的优点是边读边解析,占用内存少,解析速度快,缺点是不能对XML文件改删,并且不支持向后遍历,只能从头到尾读取.

4.1 SAX读取XML步骤

1.获取SAXParser对象,该对象通过SAXParserFactory构造

2.通过SAXParser.getXMLReader()获取XMLReder对象

3.实现一个ContentHandler的子类(PersonHandler),其实就是构造一个DefaultHandler的子类(因为contentHandler接口太多方法没实现),如下图所示:

然后重写startElement()等方法(用来实现具体的XML读取)

4.再调用XMLReder对象的setContentHandler(new PersonHandler())来设置我们要解析的具体handler

5.最后调用XMLReder对象的parse(file),开始进行解析

4.2 Myhandler需要重写的方法有以下几个

startDocument();    //当文档开始解析时,触发该方法
endDocument(); //当文档解析完成时,触发该方法 startElement(String uri, String localName, String qName, Attributes attributes)
//解析到开始元素时,触发该方法 endElement(String uri, String localName, String qName)
//解析到结束元素时,触发该方法
//uri:名称空间URI,如果元素没有名称空间,没有则为空字符串。
//localName:本地名称(不带前缀),没有则为空字符串。
//qName:元素名(带有前缀),如果元素名不可用则为空字符串。
//attributes:该元素的所有属性。如果没有属性,则为空对象. characters(char[] ch, int start, int length)
//接收字符内容时,触发该方法,比如"<姓名>李四</姓名>",当解析到"李四"时,会调用到该方法,并将"李四"作为参数传递进来.

4.3 persons.xml示例如下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persons>
<person>
<姓名>张三</姓名>
<性别>男</性别>
<年龄>99</年龄>
</person> <person>
<姓名>李四</姓名>
<性别>男</性别>
<年龄>17</年龄>
</person>
</persons>

4.4 Person类如下所示:

public class Person {
private String name;
private String sex;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";
}
}

4.5 SaxParseTest类如下所示:

package com.my.xmlparser;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.junit.Test;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import com.my.bean.Person; class PersonHandler extends DefaultHandler{
private String status=null;
private ArrayList<Person> persons=null;
private Person person=null;
@Override
public void startDocument() throws SAXException { persons = new ArrayList<Person>();
person = new Person();
} @Override
public void endDocument() throws SAXException {
for(Person person1:persons){ //打印所有信息
System.out.println(person1);
}
} @Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
status = qName;
} @Override
public void endElement(String uri, String localName, String qName) throws SAXException {
status =null;
if("person".equals(qName)) //添加一个person
{
persons.add(person);
person = new Person();
}
} @Override
public void characters(char[] ch, int start, int length) throws SAXException {
String text = new String(ch,start,length);
if(status == null)
return;
else if("姓名".equals(status))
{
person.setName(text);
}
else if("性别".equals(status))
{
person.setSex(text);
}
else if("年龄".equals(status))
{
person.setAge(text);
}
}
} public class SaxParseTest { @Test
public void SaxParse() throws Exception{
//1.获取SAXParser对象,该对象通过SAXParserFactory构造
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = saxParserFactory.newSAXParser(); //2.通过SAXParser.getXMLReader()获取XMLReder对象
XMLReader reader = saxParser.getXMLReader();
//3~4:实现一个ContentHandler的子类(Myhandler),然后来设置我们要解析的具体handler
reader.setContentHandler(new PersonHandler());
//5.最后调用XMLReder对象的parse(file),开始进行解析
reader.parse("src//persons.xml");
}
}

测试运行:

未完待续,下章学习:18.JAVA-pull解析XML

17.JAVA-Dom、Sax解析XML详解的更多相关文章

  1. Java用SAX解析XML

    要解析的XML文件:myClass.xml <?xml version="1.0" encoding="utf-8"?> <class> ...

  2. JAVA使用SAX解析XML文件

    在我的另一篇文章(http://www.cnblogs.com/anivia/p/5849712.html)中,通过一个例子介绍了使用DOM来解析XML文件,那么本篇文章通过相同的XML文件介绍如何使 ...

  3. DOM&SAX解析XML

    在上一篇随笔中分析了xml以及它的两种验证方式.我们有了xml,但是里面的内容要怎么才能得到呢?如果得不到的话,那么还是没用的,解析xml的方式主要有DOM跟SAX,其中DOM是W3C官方的解析方式, ...

  4. Java中Sax解析XML

    SAX基于事件的解析,解析器在一次读取XML文件中根据读取的数据产生相应的事件,由应用程序实现相应的事件处理逻辑,即它是一种“推”的解析方式:这种解析方法速度快.占用内存少,但是它需要应用程序自己处理 ...

  5. java使用sax解析xml

    目的:解析xml文件,并存入mysql,并且要解析的字段能一一对应.这里解析的是微博的文件,想要利用里面的article和person_id字段. 思路: 为了能得到person_id和article ...

  6. Jsoup解析Xml{详解}

    1:  概述 * 代码: //2.1获取student.xml的path String path = JsoupDemo1.class.getClassLoader().getResource(&qu ...

  7. C#解析XML详解(XPath以及带命名空间NameSpace)

    <?xml version="1.0" encoding="utf-8" ?> <bookstore> <book> < ...

  8. 简单的java使用SAX解析xml

    1.新建一个SAXTest类,继承import org.xml.sax.helpers.DefaultHandler类 package com.qiao.SrpingSource; import or ...

  9. Java DOM方式解析XML(模板)

    //创建一个DocumentBuilderFactory工厂实例 DocumentBuilderFactory DBF=DocumentBuilderFactory.newInstance(); // ...

随机推荐

  1. P3097 [USACO13DEC]最优挤奶(线段树优化dp)

    盲猜dp系列... 题意:给定序列,选了i就不能选与i相邻的两个,求最大值,带修改 蒟蒻在考场上10min打完以为只有两种情况的错解...居然能骗一点分... 先讲下当时的思路吧. f[i][0/1] ...

  2. 零基础Linux入门学习方法--如何做好笔记及长效知识复习记忆

    “工欲善其事必先利其器”. 此次学习的0基础教材为刘遄(Liu Chuán)老师的<Linux就该这么学>.学习目的是通过RHCE认证.有关RHCE认证介绍会在认识Linux及红帽认证中记 ...

  3. tomcat 日志(2)

    一.Log4j在Tomcat中的配置说明(tomcat6) 学习Java中,从简单的开始.如果需要文中提到的文件可以找我要. http://www.apache.org/dist/tomcat/tom ...

  4. 6.2.2 辅助类GenericOptionsParser,Tool和ToolRunner深入解析

    辅助类GenericOptionsParser,Tool和ToolRunner (1)为什么要用ToolRunner 将MapReduce Job配置参数写到java代码里,一旦变更意味着修改java ...

  5. 小程序 数字过千 以K显示

    先新建一个 wxs 文件 每一个 .wxs 文件和 <wxs> 标签都是一个单独的模块. 每个模块都有自己独立的作用域.即在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见. ...

  6. Redis实战--使用Jedis实现百万数据秒级插入

    echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!!! 当我们 ...

  7. ASP.NET Core 1.0: Deploy to IIS

    尽管ASP.NET最新的官方文档记录了如何Deploy to IIS,但是实际操作起来依旧磕磕绊绊.官方文档地址:https://docs.asp.net/en/latest/publishing/i ...

  8. go 学习笔记之咬文嚼字带你弄清楚 defer 延迟函数

    温故知新不忘延迟基础 A "defer" statement invokes a function whose execution is deferred to the momen ...

  9. C语言|博客作业02

    这个作业属于哪个课程 C程序语言设计 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-1/homework/8654 我在这个课程的目标是 ...

  10. Java虚拟机详解(十)------类加载过程

    在上一篇文章中,我们详细的介绍了Java类文件结构,那么这些Class文件是如何被加载到内存,由虚拟机来直接使用的呢?这就是本篇博客将要介绍的——类加载过程. 1.类的生命周期 类从被加载到虚拟机内存 ...