在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. PTA刷题记录(3)

    团队天梯赛-------(3)分值:15 给定一个 k 位整数 N=d​k−1​​10​k−1​​+⋯+d​1​​10​1​​+d​0​​ (0≤d​i​​≤9, i=0,⋯,k−1, d​k−1​​ ...

  2. PHP微信授权登录用于多个域名的方法

    PHP微信授权登录用于多个域名的方法appid和 回调地址换下就好了 <pre><!DOCTYPE html><html lang="en">& ...

  3. python面向对象<三>

    类属性.实例属性: class Tool(object): #属性(类属性)类对象(Tool) num = 0 #方法 def __init__(self,new_name): self.name = ...

  4. springboot使用dubbo和zookeeper

    2019-11-17 yls 创建服务接口模块 接口工程只提供接口,不提供实现,在后面的提供者和消费者中使用 在使用接口的模块中只需要写具体实现类,避免了在每个模块中重复编写接口 在接口中引入依赖包 ...

  5. 使用Rider中搭建specflow+xunit+selenium对web页面进行自动化功能测试环境

    运行rider,创建测试解决方案,选择xunit,点击create创建 ​   导入包,由于本人使用chrome浏览器(需先下载好对应的浏览器驱动),所以导入了selenium.webdriver.c ...

  6. linux/ubuntu下最简单好用的python opencv安装教程 ( 解决 imshow, SIFT, SURF, CSRT使用问题)

    希望这篇文章能彻底帮你解决python opencv安装和使用中的常见问题. 懒人请直奔这一节, 一条命令安装 opencv 使用python-opencv常用的问题 在linux中使用python版 ...

  7. C# Web分页功能实现

    无论是网站还是APP分页功能都是必不可少的.为什么使用分页呢? 1,加载速度快,不会占用服务器太多资源,减少服务器压力. 2,减少数据库压力. 3,提升用户体验. 那么我们常用的分页方法有两种. 1, ...

  8. python的模块future用法实例解析

    计算机的知识太多了,很多东西就是一个使用过程中详细积累的过程.最近遇到了一个很久关于future的问题,踩了坑,这里就做个笔记,免得后续再犯类似错误.   future的作用:把下一个新版本的特性导入 ...

  9. suseoj The wheat of the prime minister

    1202: 2018四川理工学院大学生ACM程序设计:The wheat of the prime minister 时间限制: 1 Sec  内存限制: 128 MB提交: 4  解决: 3[提交] ...

  10. Nginx服务器安装及配置解释

    nginx是高性能的轻量级web服务器. 特性: 1.http代理 2.反向代理 3.负载均衡 4.缓存机制 一,安装及启动(centos7,nginx 1.14.0) 1.下载 wget http: ...