XML解析之----SAX解析(带属性与不带属性)----自定义Handler类

2024-05-27 05:08

本文主要是介绍XML解析之----SAX解析(带属性与不带属性)----自定义Handler类,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在XML的解析中,有几种方式,其中用的比较多的一种是 XmlPullParserFactory, Pull解析工厂,这种比较常用,但需要借助外部jar包的支持,还有一中就是今天讲的SAXParserFactory解析工厂,他的存在意义在与不需要jar包的支持,JDK本身就可以支持!
这个是不带属性的XML文件内容:
   
<?xml version="1.0" encoding="GBK"?>
<games>
<game>
<id>1</id>
<name>完美国际2</name>
<company>完美世界</company>
</game>
<game>
<id>2</id>
<name>LOL</name>
<company>Tencent</company>
</game>
<game>
<id>3</id>
<name>DOTA</name>
<company>暴雪</company>
</game>
</games>
这个是带属性的XML文件内容:
   
<?xml version="1.0" encoding="GBK"?>
<games>
<game id="1">
<name>完美国际2</name>
<company>完美世界</company>
</game>
<game id="2">
<name>LOL</name>
<company>Tencent</company>
</game>
<game id="3">
<name>DOTA</name>
<company>暴雪</company>
</game>
</games>

下面是主类,用来实现解析已经测试解析结果!
  
package com.ctgu.sax;
 
import java.util.List;
 
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
 
import org.xml.sax.XMLReader;
 
public class TestXmlSax {
 
public static void main(String[] args) {
String path = "source/games.xml";
String path2 = "source/games2.xml";
//不带属性的XML sax 解析
System.out.println("不带属性的XML sax 解析");
List<Game> games = parserXml2(path);
for (Game game : games) {
System.out.println(game);
}
//带属性的XML sax 解析
System.out.println("带属性的XML sax 解析");
List<Game> list = parserXml3(path2);
for (Game game : list) {
System.out.println(game);
}
}
 
public static void parserXml(String path) {
try {
 
// 使用SAXParserFactory创建SAX解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
// 通过SAX解析工厂得到解析器对象
SAXParser parser = factory.newSAXParser();
// 通过解析器对象得到一个XML的读取器
XMLReader reader = parser.getXMLReader();
// 设置读取器的事件处理器
reader.setContentHandler(new MyHandler());
// 解析xml文件
reader.parse(path);
 
} catch (Exception e) {
e.printStackTrace();
}
}
// 解析不带属性的XML
public static List<Game> parserXml2(String path) {
List<Game> list = null;
try {
// 使用SAXParserFactory创建SAX解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
// 通过SAX解析工厂得到解析器对象
SAXParser parser = factory.newSAXParser();
// 通过解析器对象得到一个XML的读取器
XMLReader reader = parser.getXMLReader();
// 设置读取器的事件处理器
MyHandler2 handler2 = new MyHandler2();
reader.setContentHandler(handler2);// 解析
// 解析xml文件
reader.parse(path);
list = handler2.getList();
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
 
// 解析带属性的XML
public static List<Game> parserXml3(String path) {
List<Game> list = null;
try {
 
// 使用SAXParserFactory创建SAX解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
// 通过SAX解析工厂得到解析器对象
SAXParser parser = factory.newSAXParser();
// 通过解析器对象得到一个XML的读取器
XMLReader reader = parser.getXMLReader();
// 设置读取器的事件处理器
MyHandler3 handler3 = new MyHandler3();
reader.setContentHandler(handler3);// 解析
// 解析xml文件
reader.parse(path);
list = handler3.getList();
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
}
下面是Game类:
  
package com.ctgu.sax;
 
public class Game {
private String id;
private String name;
private String company;
public Game() {
// TODO Auto-generated constructor stub
}
public Game(String id, String name, String company) {
super();
this.id = id;
this.name = name;
this.company = company;
}
 
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
@Override
public String toString() {
return "Game [id=" + id + ", name=" + name + ", company=" + company + "]";
}
}
下面是自定的两个Handler类:
Handler2------不带属性的解析
   
package com.ctgu.sax;
 
import java.util.ArrayList;
import java.util.List;
 
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
 
/**
* 解析XML,返回List集合
* @author MXN
*
*/
public class MyHandler2 extends DefaultHandler {
 
private String tag = null;
private List<Game> list = null;
 
private Game g = null;
 
// 开始文档
@Override
public void startDocument() throws SAXException {
// System.out.println("--------startDocument");
list = new ArrayList<>();
}
 
// 结束文档
@Override
public void endDocument() throws SAXException {
//System.out.println("--------endDocument");
//System.out.println(list);
}
 
// 开始标签
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
//System.out.println("--------startElement uri=" + uri + " localName=" + localName + " qName=" + qName);
tag = qName;
if (qName.equals("game")) {
g = new Game();
}
}
 
// 结束标签
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
//System.out.println("--------endElement uri=" + uri + " localName=" + localName + " qName=" + qName);
tag = "";
if (qName.equals("game"))// 如果发现game的结束标签,说明一个game对象已经解释完成
{
list.add(g);
}
}
 
// 读取标签里面的数据
/**
* ch 整个XML文档的字符数组 start 代表,当前标签所在字符在整个数组中的开始位置 length 代表 当前标签里面字符的长度
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
//System.out.println("--------characters");
//System.out.println(tag);
if (tag.equals("id")) {
g.setId(new String(ch, start, length));
// System.out.println(new String(ch, start, length));
} else if (tag.equals("name")) {
g.setName(new String(ch, start, length));
// System.out.println(new String(ch, start, length));
} else if (tag.equals("company")) {
g.setCompany(new String(ch, start, length));
// System.out.println(new String(ch, start, length));
}
}
 
public List<Game> getList() {
return list;
}
}
Handler3-------带属性的解析
   
package com.ctgu.sax;
 
import java.util.ArrayList;
import java.util.List;
 
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
 
/*
* 解析带属性的XML
*/
public class MyHandler3 extends DefaultHandler {
 
private String tag = null;
private List<Game> list = null;
 
private Game g = null;
 
// 开始文档
@Override
public void startDocument() throws SAXException {
list = new ArrayList<>();
}
 
// 结束文档
@Override
public void endDocument() throws SAXException {
}
 
// 开始标签
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
tag = qName;
if (qName.equals("game")) {
//System.out.println(attributes.getValue("id"));
g = new Game();
g.setId(attributes.getValue("id"));
}
}
 
// 结束标签
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
tag = "";
if (qName.equals("game"))// 如果发现game的结束标签,说明一个game对象已经解释完成
{
list.add(g);
}
}
 
// 读取标签里面的数据
/**
* ch 整个XML文档的字符数组 start 代表,当前标签所在字符在整个数组中的开始位置 length 代表 当前标签里面字符的长度
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (tag.equals("name")) {
g.setName(new String(ch, start, length));
} else if (tag.equals("company")) {
g.setCompany(new String(ch, start, length));
}
}
 
public List<Game> getList() {
return list;
}
}
这是最终的解析结果:
   
不带属性的XML sax 解析
Game [id=1, name=完美国际2, company=完美世界]
Game [id=2, name=LOL, company=Tencent]
Game [id=3, name=DOTA, company=暴雪]
带属性的XML sax 解析
Game [id=1, name=完美国际2, company=完美世界]
Game [id=2, name=LOL, company=Tencent]
Game [id=3, name=DOTA, company=暴雪]

这篇关于XML解析之----SAX解析(带属性与不带属性)----自定义Handler类的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1006582

相关文章

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

MyBatis常用XML语法详解

《MyBatis常用XML语法详解》文章介绍了MyBatis常用XML语法,包括结果映射、查询语句、插入语句、更新语句、删除语句、动态SQL标签以及ehcache.xml文件的使用,感兴趣的朋友跟随小... 目录1、定义结果映射2、查询语句3、插入语句4、更新语句5、删除语句6、动态 SQL 标签7、ehc

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

一文解析C#中的StringSplitOptions枚举

《一文解析C#中的StringSplitOptions枚举》StringSplitOptions是C#中的一个枚举类型,用于控制string.Split()方法分割字符串时的行为,核心作用是处理分割后... 目录C#的StringSplitOptions枚举1.StringSplitOptions枚举的常用

Python函数作用域与闭包举例深度解析

《Python函数作用域与闭包举例深度解析》Python函数的作用域规则和闭包是编程中的关键概念,它们决定了变量的访问和生命周期,:本文主要介绍Python函数作用域与闭包的相关资料,文中通过代码... 目录1. 基础作用域访问示例1:访问全局变量示例2:访问外层函数变量2. 闭包基础示例3:简单闭包示例4

MyBatis延迟加载与多级缓存全解析

《MyBatis延迟加载与多级缓存全解析》文章介绍MyBatis的延迟加载与多级缓存机制,延迟加载按需加载关联数据提升性能,一级缓存会话级默认开启,二级缓存工厂级支持跨会话共享,增删改操作会清空对应缓... 目录MyBATis延迟加载策略一对多示例一对多示例MyBatis框架的缓存一级缓存二级缓存MyBat

前端缓存策略的自解方案全解析

《前端缓存策略的自解方案全解析》缓存从来都是前端的一个痛点,很多前端搞不清楚缓存到底是何物,:本文主要介绍前端缓存的自解方案,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、为什么“清缓存”成了技术圈的梗二、先给缓存“把个脉”:浏览器到底缓存了谁?三、设计思路:把“发版”做成“自愈”四、代码

Java集合之Iterator迭代器实现代码解析

《Java集合之Iterator迭代器实现代码解析》迭代器Iterator是Java集合框架中的一个核心接口,位于java.util包下,它定义了一种标准的元素访问机制,为各种集合类型提供了一种统一的... 目录一、什么是Iterator二、Iterator的核心方法三、基本使用示例四、Iterator的工

vue监听属性watch的用法及使用场景详解

《vue监听属性watch的用法及使用场景详解》watch是vue中常用的监听器,它主要用于侦听数据的变化,在数据发生变化的时候执行一些操作,:本文主要介绍vue监听属性watch的用法及使用场景... 目录1. 监听属性 watch2. 常规用法3. 监听对象和route变化4. 使用场景附Watch 的