首先简单介绍下XML,同时说明为什么XML文件在Internet中如此重要,在网络间获取信息的格式是XML的格式而不是别的?
XML文件是可扩展标记语言,与html一样是标准的通用标是一种简单的数据存储语言,使用一系列简单的标记描述数据,一个简单的xml结构示意图如下:
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<span style="white-space:pre"> </span><person id="23">
<span style="white-space:pre"> <span style="background-color: rgb(255, 0, 0);"> </span></span><name>lwb</name>
<span style="white-space:pre"> </span><age>24</age>
<span style="white-space:pre"> </span></person>
<span style="white-space:pre"> </span><person id="21">
<span style="white-space:pre"> </span><name>liuhuan</name>
<span style="white-space:pre"> </span><age>22</age>
<span style="white-space:pre"> </span></person>
</persons>
图中表明了元素、文本节点、以及属性值他们三者各自的位置。
其中,persons、person、name这些都称为元素(Element),而 id="23",这里的id被称为是元素内的属性,而在<name>lwb</lwb>中的lwb被称为文本(TextNode);
ps: 在xml文件中,有可能在文本节点中出现空白,但这个是正确的,因为对xml文件而言,他对于TAB键以及回车,换行都是有效的
xml他是数据内容的一种表现形式,这是他与html最大的区别(html注重的是数据的显示方式)
关于SAX解析xml文件,具体方式如下:
xml文件被Sax解析器载入,由于Sax解析是按照xml文件的顺序来解析,当读入<?xml.....>时,会调用startDocument()方法,当读入<persons>的时候,由于它是个ElementNode,所以会调用startElement(String uri, String localName, String qName, Attributes attributes) 方法,其中第二个参数和第三个参数均为节点的名称,只是第三个是有前缀的;注意:由于有些环境不一样,有时候第二个参数有可能为空,所以可以使用第三个参数,因此在解析前,先调用一下看哪个参数能用,第4个参数是这个节点的属性。这里为id,所以从<persons>这个节点开始,当读入时,调用startElement(....)方法,由于只有一个属性id,可以通过attributes.getValue(0)来得到,然后在图中标明(红色块 )的地方会调用characters(char[] ch, int start, int length)方法,不要以为那里是空白,Sax解析器可不那么认为,Sax解析器会把它认为是一个TextNode。但是这个空白不是我们想要的数据,我们是想要<name>节点下的文本信息。这就要定义一个记录当上一节点的名称的TAG,在characters(.....)方法中,判断当前节点是不是name,是再取值,才能取到thinking in java。具体见代码:
package com.lwb.main;
import java.util.ArrayList;
import java.util.List;
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;
import com.lwb.person.Person;
public class MainTest extends DefaultHandler {
private List<Person> persons;
private String perTag;
private Person person;
public List getPersons(){
return persons;
}
@Override
public void startDocument() throws SAXException {
System.out.println("-------------start document---------");
persons=new ArrayList<Person>();
}
@Override
public void endDocument() throws SAXException {
System.out.println("====endDocument=========");
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
System.out.println("-------startElement-----------");
if ("person".equals(qName)) {
for (int i = 0; i < attributes.getLength(); i++) {
System.out.println("attribute_name=="+attributes.getLocalName(i));
System.out.println("attribute_value=="+attributes.getValue(i));
person=new Person();
person.setId(Integer.valueOf(attributes.getValue(i)));
}
}
perTag=qName;
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
perTag=qName;
System.out.println("=========endElement==========");
if ("person".equals(perTag)&&person!=null) {
persons.add(person);
person=null;
}
perTag=null;
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
String data=new String(ch,start,length).trim();
if (!"".equals(data.trim())) {
System.out.println("content==="+data.trim());
}
if ("name".equals(perTag)) {
person.setName(data);
}
else if ("age".equals(perTag)) {
person.setAge(new Integer(data));
}
}
public static void main(String[] args) {
SAXParserFactory factory=SAXParserFactory.newInstance();
try {
SAXParser parser=factory.newSAXParser();
MainTest test=new MainTest();
parser.parse("NewFile.xml",test);
System.out.println("persons list===="+test.getPersons());
} catch (Exception e) {
System.out.println("can't create parser!!");
}
}
}
-------------start document---------
-------startElement-----------
localName=== qName==persons
-------startElement-----------
localName=== qName==person
attribute_name==id
attribute_value==23
-------startElement-----------
localName=== qName==name
content===lwb
=========endElement==========
perTag===name
-------startElement-----------
localName=== qName==age
content===24
=========endElement==========
perTag===age
=========endElement==========
perTag===person
-------startElement-----------
localName=== qName==person
attribute_name==id
attribute_value==21
-------startElement-----------
localName=== qName==name
content===liuhuan
=========endElement==========
perTag===name
-------startElement-----------
localName=== qName==age
content===22
=========endElement==========
perTag===age
=========endElement==========
perTag===person
=========endElement==========
perTag===persons
====endDocument=========
persons list====[Person [id=23, name=lwb, age=24], Person [id=21, name=liuhuan, age=22]]
到此,一个xml文件便解析完毕,由于sam解析器本身并不在内存中生成dom那样的树形结构,所以非常适合在android这样的嵌入式设备上使用