在这三种解析中sax解析最不耗内存。
1、dom解析
第一步:定义一个实体类用来存放XML文件节点的值
public class Book {
//定义属性用来保存XML节点信息
private int id;
private String name;
private float price;
//获得geter seter方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
//复写toString()方法
@Override
public String toString() {
return this.id + ":" + this.name + ":" + this.price;
}
}
第二步、从服务器读取XML文件数据
public class HttpUtils {
/**
* 从服务器获得xml文件返回流
* @param path
* @return
*/
public static InputStream getXML(String path) {
InputStream inputStream = null;
try {
URL url = new URL(path);
if (url != null) {
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setConnectTimeout(3000);
connection.setDoInput(true);
connection.setRequestMethod("GET");
int code = connection.getResponseCode();
if (code == 200) {
inputStream = connection.getInputStream();
}
}
} catch (Exception e) {
// TODO: handle exception
}
return inputStream;
}
}
第三步,解析从服务器获得的流式数据
public class DomParseService {
public DomParseService() {
// TODO Auto-generated constructor stub
}
public List<Book> getBooks(InputStream inputStream) throws Exception {
List<Book> list = new ArrayList<Book>();
//获得DOM解析工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//获得一个DOM解析引用
DocumentBuilder builder = factory.newDocumentBuilder();
//解析输入流获得Document引用
Document document = builder.parse(inputStream);
//获得Document引用的元素
Element element = document.getDocumentElement();
NodeList bookNodes = element.getElementsByTagName("book");
for (int i = 0; i < bookNodes.getLength(); i++) {
Element bookElement = (Element) bookNodes.item(i);
Book book = new Book();
//设置标签最近属性的值
book.setId(Integer.parseInt(bookElement.getAttribute("id")));
//获得当前标签的子节点
NodeList childNodes = bookElement.getChildNodes();
// System.out.println("*****"+childNodes.getLength());
for (int j = 0; j < childNodes.getLength(); j++) {
//判断是否是节点元素
if (childNodes.item(j).getNodeType() == Node.ELEMENT_NODE) {
//进一步判断是具体的
if ("name".equals(childNodes.item(j).getNodeName())) {
book.setName(childNodes.item(j).getFirstChild()
.getNodeValue());
} else if ("price".equals(childNodes.item(j).getNodeName())) {
book.setPrice(Float.parseFloat(childNodes.item(j)
.getFirstChild().getNodeValue()));
}
}
}// end for j
list.add(book);
}// end for i
return list;
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
String path = "http://192.168.56.1:8080/myhttp/book.xml";
InputStream input = HttpUtils.getXML(path);
DomParseService dom = new DomParseService();
List<Book> books = dom.getBooks(input);
for (Book book : books) {
System.out.println(book.toString());
}
}
}
2、sax解析
解析文档如下:
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student id="23">
<name>jack</name>
<age>30</age>
</student>
<student id="20">
<name>rose</name>
<age>25</age>
</student>
</students>
具体代码:
第一步:写一个DefaultHandler的子类
public class MyHandler extends DefaultHandler {
private HashMap<String,String> map=null;//用于存储单条解析的完整对象
private List<HashMap<String,String>> list=null;//存储所有解析的结果.设置他的get方法用于获得解析的结果
private String currentTag=null;//当前解析元素的标签
private String currentValue=null;//当前解析元素的值
private String nodeName=null;//解析元素的所在的节点(每一组对象)
//构造方法,每次传入一个节点也是一个对象进行解析
public MyHandler(String nodeName) {
this.nodeName=nodeName;
}
/**
* @return the list
*/
public List<HashMap<String, String>> getList() {
return list;
}
@Override
public void startDocument() throws SAXException {
//文档开头students
super.startDocument();
//当读到第一各标签的时候执行该方法
list= new ArrayList<HashMap<String,String>>();
}
//每个对象
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
//遇到元素就执行该方法
//判断当前节点是否是是要解析的节点
if(qName==nodeName)
{
//存放每个节点解析的结果
map=new HashMap<String,String>();
}
//判断节点里的属性是否为空
if(attributes!=null&&map!=null)
{
for(int i=0;i<attributes.getLength();i++)
{
//把属性值存入集合中
map.put(attributes.getQName(i),attributes.getValue(attributes.getQName(i)));
}
}
//当前的标签变成该解析的节点
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文件的要读取的内容
//如果当前的标签不为空 集合也不为空,则
if(currentTag!=null&&map!=null)
{
//获得该标签的当前值
currentValue=new String(ch,start,length);
//判断该值是否为空,是否为空格,是否为回车
if(currentValue!=null&¤tValue!=""&¤tValue!="\n")
{
//把数据放入集合中
map.put(currentTag,currentValue);
}
}
//把当前节点的标签和值设置为空
currentTag=null;
currentValue=null;
}
@Override
public void endElement (String uri, String localName, String qName)
throws SAXException {
//遇到结束标记时执行该方法
if(qName==nodeName)
{
//把元素加入集合中,并把上一个节点的放在集合Map中的数据清空
list.add(map);
map=null;
}
// TODO Auto-generated method stub
super.endElement(uri, localName, qName);
}
}
第二步:
public class SaxService {
public SaxService() {
}
nodeName:是student
public static List<HashMap<String, String>> readXML(
InputStream inputStream, String nodeName) {
List<HashMap<String, String>> list=null;
try{
//创建解析XML的工厂对象
SAXParserFactory spf=SAXParserFactory.newInstance();
//获得解析XML内容的解析对象用于XML解析
SAXParser parser=spf.newSAXParser();
//获得一个 DefaultHandler对象
MyHandler handler=new MyHandler(nodeName);
parser.parse(inputStream, handler);
inputStream.close();
return handler.getList();
}catch(Exception e)
{
}
return null;
}
}
工具类:
public class HttpUtils {
public HttpUtils() {
// TODO Auto-generated constructor stub
}
public static InputStream getXML(String path)
{
InputStream inputStream=null;
InputStream inputStream2=null;
try {
String result=null;
//定义一个资源定位器
URL url=new URL(path);
//获得服务器连接
try {
//通过调用URL的openConnection()获得服务器连接对象
HttpURLConnection urlConnection= (HttpURLConnection) url.openConnection();
//连接对象的设置
//设置请求时间
urlConnection.setConnectTimeout(3000);
//设置请求方式
urlConnection.setRequestMethod("GET");
//设置可以后的输入流从服务器里读取数据
urlConnection.setDoInput(true);
//获得请求结果码
int codeResponse=urlConnection.getResponseCode();
//判断结果码
if(codeResponse==200)
{
//获得输入流
inputStream=urlConnection.getInputStream();
/*
if(inputStream!=null){
File file=new File("E:\\test.txt");
FileOutputStream os=new FileOutputStream(file);
//读取输入流数据
int len=0;
byte[] buffer=new byte[1024];
while((len=inputStream.read(buffer))!=-1)
{
//把数据写入输出流
os.write(buffer);
}
}*/
System.out.println(inputStream.toString());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return inputStream;
}
}
测试:
public class Test {
public Test() {
}
public static void main(String[] args) {
String path="http://192.168.56.1:8080/myhttp/students.xml";
InputStream in=HttpUtils.getXML(path);
try{
//获得XML内容
List<HashMap<String,String>> list=SaxService.readXML(in, "student");
/*for(int i=0;i<list.size();i++)
{
HashMap<String,String> map=new HashMap<String,String>();
map=list.get(i);
System.out.print(map.toString());
}
*/
for(HashMap<String,String> map:list)
{
System.out.print(map.toString());
}
}catch(Exception e)
{
}
}
}
3、pull解析
第一步:定义一个实体类
public class Person {
//定义标签属性
private int id;
private String name;
private int age;
//设置标签属性的seter,geter方法
public int getId() {
return id;
}
public Person(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//构造方法
public Person() {
// TODO Auto-generated constructor stub
}
//复写toString方法
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
第二步、从服务器获得数据输入流并通过方法返回给解析对象
public class HttpUtils {
/**
* 从服务器获得xml文件返回流
* @param path
* @return
*/
public static InputStream getXML(String path) {
InputStream inputStream = null;
try {
//定义资源定位器
URL url = new URL(path);
if (url != null) {
//获得服务器连接
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
//服务器设置
//设置连接超时
connection.setConnectTimeout(3000);
//设置可以获得服务器的输入流
connection.setDoInput(true);
//设置URL连接请求方式
connection.setRequestMethod("GET");
//获得响应码
int code = connection.getResponseCode();
if (code == 200) {
//获得输入流用于读数据
inputStream = connection.getInputStream();
}
}
} catch (Exception e) {
// TODO: handle exception
}
return inputStream;
}
}
第三步、解析对象
/**
* 主要是使用PULL解析xml
*
* @author jack
*
*/
public class PullXMLTools {
public PullXMLTools() {
// TODO Auto-generated constructor stub
}
/**
* @param inputStream
* 从服务器获取xml文件,以流的形式返回
* @param encode
* 编码格式
* @return
* @throws Exception
*/
public static List<Person> parseXML(InputStream inputStream, String encode)
throws Exception {
List<Person> list = null;
Person person = null;// 装载解析每一个person节点的内容
// 创建一个xml解析的工厂
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
// 获得xml解析类的引用
XmlPullParser parser = factory.newPullParser();
parser.setInput(inputStream, encode);
// 获得事件的类型
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
list = new ArrayList<Person>();
break;
case XmlPullParser.START_TAG:
if ("person".equals(parser.getName())) {
person = new Person();
// 取出属性值
int id = Integer.parseInt(parser.getAttributeValue(0));
person.setId(id);
} else if ("name".equals(parser.getName())) {
String name = parser.nextText();// 获取该节点的内容
person.setName(name);
} else if ("age".equals(parser.getName())) {
int age = Integer.parseInt(parser.nextText());
person.setAge(age);
}
break;
case XmlPullParser.END_TAG:
if ("person".equals(parser.getName())) {
list.add(person);
person = null;
}
break;
}
eventType = parser.next();
}
return list;
}
}
客户端测试:
public class Test {
public Test() {
// TODO Auto-generated constructor stub
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String path = "http://192.168.56.1:8080/myhttp/person.xml";
InputStream inputStream = HttpUtils.getXML(path);
List<Person> list = null;
try {
list = PullXMLTools.parseXML(inputStream, "utf-8");
for (Person person : list) {
System.out.println(person.toString());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
4、XML文档结构