使用sax解析xml文件

时间:2022-11-16 16:01:27

老罗视频学习。


解析xml文件有三种方式,sax,pull,dom。dom占用资源比较大,sax和pull比较轻便,所以android开发一般多用sax和pull方式。

需要解析的person.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="23">
<name>李老师</name>
<age>23</age>
</person>
<person id = "24">
<name>张老师</name>
<age>26</age>
</person>
</persons>



一.客户端。

项目结构如下:

1)先声明一个com.sax.handler包下的类MyHandler类继承DefaultHandle。通过startDocument函数,startElement函数,characters函数和endElement函数来解析xml文件。

2)使用com.sax.http包下的类HttpUtils从服务器端把xml文件以IO流的方式返回。运用之前学习的http的get方式。

3)在com.sax.service包下的saxService类中编写业务逻辑,把IO流的数据写入list,list中的map键值对。

4)com.sax.test包中的类Test.java来写测试代码。

MyHandler内容如下:

public class MyHandler extends DefaultHandler {
private HashMap<String, String> map = null;//存储单个解析的完整对象
private List<HashMap<String, String>> list = null;//存储所有的解析对象
private String currentTag = null;//正在解析的元素的标签
private String currentValue = null;//解析当前元素的值
private String nodeName = null;//解析当前的节点名称



public List<HashMap<String, String>> getList() {
return list;
}







public MyHandler(String nodeName) {
// TODO Auto-generated constructor stub
this.nodeName = nodeName;
}

@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
//super.startDocument();
//当读到第一个开始标签的时候,会触发这个方法
//解析persons
list = new ArrayList<HashMap<String,String>>();
}

@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
//super.startElement(uri, localName, qName, attributes);
//当遇到文档的开头的时候,调用这个方法
//解析person
System.out.print("nodename--->"+nodeName+"\n");
System.out.print("qName--->"+qName+"\n");
if(qName.equals(nodeName)){
map = new HashMap<String, String>();
}
if(attributes!=null&&map!=null){
//循环遍历当前节点
int count = attributes.getLength();
System.out.print("count----->");
System.out.print(count);
System.out.print("\n");
for (int i = 0; i < attributes.getLength(); i++) {
map.put(attributes.getQName(i), attributes.getValue(i));

System.out.print("attributes--->"+attributes.getValue(i)+"\n");
}
}
currentTag = qName;
}

@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
//super.characters(ch, start, length);
//这个函数是用来处理xml文件所读取到的内容
//解析name和age了
if(currentTag!=null&&map!=null) {

currentValue = new String(ch, start,length);

if(currentValue !=null && !currentValue.trim().equals("")&&!currentValue.trim().equals("\n")){
map.put(currentTag, currentValue);
System.out.print("currentValue--->"+currentValue+"\n\n");
}
}
currentTag = null;
currentValue = null;
}




@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
//
//遇到结束标记的时候,会调用这个方法
if(qName.equals(nodeName)) {
list.add(map);
map=null;
}
super.endElement(uri, localName, qName);
}


}

运行结果如下,附加有system输出信息:

nodename--->person
qName--->persons
nodename--->person
qName--->person
count----->1
attributes--->23
nodename--->person
qName--->name
count----->0
currentValue--->李老师

nodename--->person
qName--->age
count----->0
currentValue--->23

nodename--->person
qName--->person
count----->1
attributes--->24
nodename--->person
qName--->name
count----->0
currentValue--->张老师

nodename--->person
qName--->age
count----->0
currentValue--->26

{id=23, age=23, name=李老师}
{id=24, age=26, name=张老师}

HttpUtils.java内容如下:

通过http的get方式从服务器获取流数据,这里不再详细说了

public class HttpUtils {

public HttpUtils() {
// TODO Auto-generated constructor stub
}

public static InputStream getXML(String path) {


InputStream inputStream = null;
try {
URL url = new URL(path);

HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
httpURLConnection.setConnectTimeout(3000);
httpURLConnection.setDoInput(true);
httpURLConnection.setRequestMethod("GET");
int responseCode = httpURLConnection.getResponseCode();
if(responseCode == 200) {
inputStream = httpURLConnection.getInputStream();
}


} catch (Exception e) {
// TODO: handle exception
}

return inputStream;
}
}

SaxService.java类内容如下:


public class saxService {

public saxService() {
// TODO Auto-generated constructor stub
}

public static List<HashMap<String, String>> readXML(InputStream inputStream ,String nodeName){



try {
//创建一个解析xml的工厂对象
SAXParserFactory spfFactory = SAXParserFactory.newInstance();
//解析xml
SAXParser parser = spfFactory.newSAXParser();
//声明MyHandler对象
MyHandler handler = new MyHandler(nodeName);
parser.parse(inputStream, handler);

inputStream.close();
//调用MyHandler中的函数getList();
return handler.getList();
} catch (Exception e) {
// TODO: handle exception
}

return null;
}

}


测试类Test.java如下:

public class Test {

public Test() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
// TODO Auto-generated method stub
String pathString = "http://localhost:8080/myhttp/person.xml";
//从服务器中获取InputStream流
InputStream inputStream = HttpUtils.getXML(pathString);
try {

//把获取到的inputstream流存入list中
List<HashMap<String , String >> list = saxService.readXML(inputStream, "person");
//循环输出
for(HashMap<String, String> map : list) {
System.out.println(map.toString());
}
} catch (Exception e) {
// TODO: handle exception
}
}

}

二.服务器端还用之前的myhttp服务器,在WebContent目录下放person.xml文件,启动服务器即可。


使用sax解析xml文件