Java 操作 xml 文件之 SAX 解析
- dom4j 解析:文档对象模型解析,是W3C指定的一套规范标准。需要把整个文档读取到内存中,占用内存大,解析慢,但是访问效率高,增删改查快。适合解析小型文档。
- SAX 解析:基于事件驱动解析文档,边读边解析,不必解析整个文档,解析速度快,但是访问效率低,只能从开始顺序解析。
2、SAX 解析
SAX 解析是基于事件驱动的,先介绍以下五个方法:
(1) void startDocument(); 解析文档开始时执行
(2) void endDocument(); 解析文档结束时执行
(3) void startElement(String uri, String localName, String qName,Attributes attributes); 遇到元素开始节点时执行
(4) void characters(char[] ch, int start, int length); 两尖括号之间时执行
(5) void endElement(String uri, String localName, String qName); 遇到元素结束节点时执行
输出到控制台
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXParserHandler extends DefaultHandler {
int comIndex = 0;
// 用来标识解析开始
@Override
public void startDocument() throws SAXException {
super.startDocument();
System.out.println("SAX解析开始");
}
// 用来标识解析结束
@Override
public void endDocument() throws SAXException {
super.endDocument();
System.out.println("SAX解析结束");
}
// 解析xml元素,每到开始标签都会调用下面这个方法
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// 调用defaultHandler类的startElement方法
super.startElement(uri, localName, qName, attributes);
if (!qName.equals("city")&&!qName.equals("company")&&!qName.equals("person")) {
System.out.print("节点名是:" + qName);
}
if (qName.equals("company")) {
comIndex++;
System.out.println("开始遍历第" + comIndex + "个公司资料");
System.out.println("节点名是:" + qName);
}
// 开始解析company元素的属性(已知company元素下的属性名称,根据名称获取属性值)
if (qName.equals("company")) {
String value = attributes.getValue("unitId");
System.out.println("company的unitId属性值是" + value);
String value2 = attributes.getValue("unitCode");
System.out.println("company的unitCode属性值是" + value2);
String value3 = attributes.getValue("unitName");
System.out.println("company的unitName属性值是" + value3);
}
/*
// 不知道元素节点中属性的名称及个数,如何获取属性名和属性值
int num = attributes.getLength();// 返回book元素下属性的个数
for (int i = 0; i < num; i++) {
System.out.print("company元素的第" + (i + 1) + "个属性名是:" + attributes.getQName(i));
System.out.println("---属性值是:" + attributes.getValue(i));
}
*/
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(uri, localName, qName);
// 判断是否对某一元素节点已经遍历结束
if (qName.equals("company")) {
System.out.println("结束遍历第" + comIndex + "个公司的资料");
System.out.println();
}
}
@Override
// char[] ch代表相邻两个尖括号<>之间的内容
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
String value = new String(ch, start, length);
if (!value.trim().equals("")) {
System.out.println("=="+value);
}
}
public static void main(String[] args) {
String pathname = "E://temptest//xmlTest.xml";
// 获取SAXParserFactory实例
SAXParserFactory factory=SAXParserFactory .newInstance();
//获取SAXParse的实例
try {
SAXParser parser=factory.newSAXParser();
//创建SAXParserHandler对象
SAXParserHandler handler=new SAXParserHandler();
parser.parse(pathname, handler);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
封装成对象
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXReadXml extends DefaultHandler {
private List<Map<String,String>> conList= new ArrayList<Map<String,String>>();
private HashMap<String, String> map;// 用来封装 company 对象ֵ
private String elementName;// 节点名称
public void reader(String pathfile) {
InputStream inStream = null;
try {
inStream = new FileInputStream(pathfile);
SAXParserFactory saxfac = SAXParserFactory.newInstance();
SAXParser saxParser = saxfac.newSAXParser();
saxParser.parse(inStream, this);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
StringBuffer text = new StringBuffer("");
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
elementName = qName;
if (qName.equals("company")||qName.equals("person")) {
map = new HashMap<String, String>();
}
}
@Override
public void characters(char[] ch, int start, int length)throws SAXException {
if (map != null && elementName != null) {
String content = new String(ch, start, length);
if (content.trim().length() > 0) {
text.append(new String(ch, start, length));
map.put(elementName, text.toString());
}
//如果是用某个对象的set方法赋值,则先判断节点名称
// if(elementName.equals("userName")) {
// user.setName(text.toString()); //假设给user对象的name赋值
// }
}
}
@Override
public void endElement(String uri, String localName, String qName)throws SAXException {
// if (qName.equals("company")||qName.equals("person")){ //把 company 和 person 的对象添加到 list
// conList.add(map);
// }
if (qName.equals("company")) {//只把 company 的对象添加到 list
conList.add(map);
}
elementName = null;
text = new StringBuffer("");
}
//用来返回封装好的对象列表
public List<Map<String,String>> getCompanyList(){
return conList;
}
public static void main(String[] args) {
SAXReadXml xml = new SAXReadXml();
xml.reader("E:\\temptest\\xmlTest.xml");
List<Map<String,String>> list = xml.getCompanyList();
for(Map<String,String> com:list){
System.out.println(com);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
不管我们要哪类还是哪个元素节点的内容,只要在 startElement 方法、characters 方法、endElement 方法中加入相应的判断、逻辑,就能解析到我们想要的内容,所以,尽管 SAX 解析比较麻烦,但是更灵活。
- dom4j 解析:文档对象模型解析,是W3C指定的一套规范标准。需要把整个文档读取到内存中,占用内存大,解析慢,但是访问效率高,增删改查快。适合解析小型文档。
- SAX 解析:基于事件驱动解析文档,边读边解析,不必解析整个文档,解析速度快,但是访问效率低,只能从开始顺序解析。
2、SAX 解析
SAX 解析是基于事件驱动的,先介绍以下五个方法:
(1) void startDocument(); 解析文档开始时执行
(2) void endDocument(); 解析文档结束时执行
(3) void startElement(String uri, String localName, String qName,Attributes attributes); 遇到元素开始节点时执行
(4) void characters(char[] ch, int start, int length); 两尖括号之间时执行
(5) void endElement(String uri, String localName, String qName); 遇到元素结束节点时执行
输出到控制台
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXParserHandler extends DefaultHandler {
int comIndex = 0;
// 用来标识解析开始
@Override
public void startDocument() throws SAXException {
super.startDocument();
System.out.println("SAX解析开始");
}
// 用来标识解析结束
@Override
public void endDocument() throws SAXException {
super.endDocument();
System.out.println("SAX解析结束");
}
// 解析xml元素,每到开始标签都会调用下面这个方法
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// 调用defaultHandler类的startElement方法
super.startElement(uri, localName, qName, attributes);
if (!qName.equals("city")&&!qName.equals("company")&&!qName.equals("person")) {
System.out.print("节点名是:" + qName);
}
if (qName.equals("company")) {
comIndex++;
System.out.println("开始遍历第" + comIndex + "个公司资料");
System.out.println("节点名是:" + qName);
}
// 开始解析company元素的属性(已知company元素下的属性名称,根据名称获取属性值)
if (qName.equals("company")) {
String value = attributes.getValue("unitId");
System.out.println("company的unitId属性值是" + value);
String value2 = attributes.getValue("unitCode");
System.out.println("company的unitCode属性值是" + value2);
String value3 = attributes.getValue("unitName");
System.out.println("company的unitName属性值是" + value3);
}
/*
// 不知道元素节点中属性的名称及个数,如何获取属性名和属性值
int num = attributes.getLength();// 返回book元素下属性的个数
for (int i = 0; i < num; i++) {
System.out.print("company元素的第" + (i + 1) + "个属性名是:" + attributes.getQName(i));
System.out.println("---属性值是:" + attributes.getValue(i));
}
*/
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(uri, localName, qName);
// 判断是否对某一元素节点已经遍历结束
if (qName.equals("company")) {
System.out.println("结束遍历第" + comIndex + "个公司的资料");
System.out.println();
}
}
@Override
// char[] ch代表相邻两个尖括号<>之间的内容
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
String value = new String(ch, start, length);
if (!value.trim().equals("")) {
System.out.println("=="+value);
}
}
public static void main(String[] args) {
String pathname = "E://temptest//xmlTest.xml";
// 获取SAXParserFactory实例
SAXParserFactory factory=SAXParserFactory .newInstance();
//获取SAXParse的实例
try {
SAXParser parser=factory.newSAXParser();
//创建SAXParserHandler对象
SAXParserHandler handler=new SAXParserHandler();
parser.parse(pathname, handler);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
封装成对象
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXReadXml extends DefaultHandler {
private List<Map<String,String>> conList= new ArrayList<Map<String,String>>();
private HashMap<String, String> map;// 用来封装 company 对象ֵ
private String elementName;// 节点名称
public void reader(String pathfile) {
InputStream inStream = null;
try {
inStream = new FileInputStream(pathfile);
SAXParserFactory saxfac = SAXParserFactory.newInstance();
SAXParser saxParser = saxfac.newSAXParser();
saxParser.parse(inStream, this);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
StringBuffer text = new StringBuffer("");
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
elementName = qName;
if (qName.equals("company")||qName.equals("person")) {
map = new HashMap<String, String>();
}
}
@Override
public void characters(char[] ch, int start, int length)throws SAXException {
if (map != null && elementName != null) {
String content = new String(ch, start, length);
if (content.trim().length() > 0) {
text.append(new String(ch, start, length));
map.put(elementName, text.toString());
}
//如果是用某个对象的set方法赋值,则先判断节点名称
// if(elementName.equals("userName")) {
// user.setName(text.toString()); //假设给user对象的name赋值
// }
}
}
@Override
public void endElement(String uri, String localName, String qName)throws SAXException {
// if (qName.equals("company")||qName.equals("person")){ //把 company 和 person 的对象添加到 list
// conList.add(map);
// }
if (qName.equals("company")) {//只把 company 的对象添加到 list
conList.add(map);
}
elementName = null;
text = new StringBuffer("");
}
//用来返回封装好的对象列表
public List<Map<String,String>> getCompanyList(){
return conList;
}
public static void main(String[] args) {
SAXReadXml xml = new SAXReadXml();
xml.reader("E:\\temptest\\xmlTest.xml");
List<Map<String,String>> list = xml.getCompanyList();
for(Map<String,String> com:list){
System.out.println(com);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
不管我们要哪类还是哪个元素节点的内容,只要在 startElement 方法、characters 方法、endElement 方法中加入相应的判断、逻辑,就能解析到我们想要的内容,所以,尽管 SAX 解析比较麻烦,但是更灵活。