xml解析
JAVA 解析 XML 通常有两种方式:DOM 和SAX。DOM(文档对象模型)是W3C标准,提供了标准的解析方式,但其解析效率一直不尽如人意,这是因为DOM解析XML文档时,把所有内容一次性的装载入内存,并构建一个驻留在内存中的树状结构(节点数)。如果需要解析的XML文档过大,或者我们只对该文档中的一部分感兴趣,这样就会引起性能问题。
SAX(simple API for XML)是一种XML解析的替代方法。相比于DOM,SAX是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。而且相比于DOM,SAX可以在解析文档的任意时刻停止解析,但任何事物都有其相反的一面,对于SAX来说就是操作复杂。
SAX是事件驱动型XML解析的一个标准接口不会改变 SAX的工作原理简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。
对于一个XML文档举例来说 <doc>
<para>Hello,World!</para>
</doc>
其解析的过程为:
1.start document
2.start element:doc......
3.start element:para.....
4.characters:Hello,World!
5.end element:para......
6.end element;doc......
7.end document
对于解析过程中的每一步都会有事件发生,都会触发相应接口中的事件处理程序。
编写程序的步骤为:
(1).创建事件处理程序(也就是编写ContentHandler的实现类,一般继承自DefaultHandler类,采用adapter模式)
(2).创建SAX解析器
(3).将事件处理程序分配到解析器
(4).对文档进行解析,将每个事件发送给事件处理程序
/*
* xml文档的格式:
* <persons>
* <person id="23">
* <name>NEWii</name>
* <age>23</age>
* </person>
* <person id="22">
* <name> Wii</name>
* <age>25</age>
* </person>
* </persons>
*
*应用中应该添加的代码:
*InputStream is=XMLactivity.class.getClassLoader().getResourceAsStream("person.xml");
*SaxForHandler handler=new SaxForHandler();
*SAXParserFactory spf=SAXparserFactory.newInstance();
*SAXParser saxParser=spf.newSAXParser();
*saxParser.parse(is,handler);
*List<Person> list=handler.getPersons();
*is.close();
*return list;
* */
public class SaxForHandler extends DefaultHandler {
private static final String TAG="SaxForHandler";
private List<Person> persons ;
private String perTag ;//通过此变量,记录前一个标签的名称
Person person; //记录当前person
public SaxForHandler() {
// TODO Auto-generated constructor stub
}
public List<Person> getPersons(){
return persons ;
}
//遇到textNode时的操作
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
super.characters(ch, start, length);
String data= new String(ch,start,length).trim();
if(!"" .equals(data.trim())){
}
if("name" .equals(perTag )){
person.setName(data);
} else if ("age" .equals(perTag )){
person.setAge( new Short(data));
}
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
super.endDocument();
Log. i(TAG, "***endDocument()****");
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
super.endElement(uri, localName, qName);
if("person" .equals(localName)){
persons.add( person);
}
person= null;
}
//在此事件中作初始化行为
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
super.startDocument();
persons= new ArrayList<Person>();
}
@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);
if("person" .equals(localName)){
for(int i=0;i<attributes.getLength();i++){
person= new Person();
person.setId(Integer. valueOf(attributes.getValue(i)));
}
}
perTag=localName; //记录Element的值
}
}
文件对象模型(Document Object Model,简称DOM。
public static List<Person> getPersons(InputStream in) throws ParserConfigurationException, SAXException, Exception{
List<Person> persons= new ArrayList<Person>();
DocumentBuilderFactory factory=DocumentBuilderFactory. newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document document=builder.parse(in);
Element root= document.getDocumentElement(); //根node
NodeList personNodes=root.getElementsByTagName( "person");
for(int i=0;i<personNodes.getLength();i++){
Element personElement=(Element)personNodes.item(i);
int id= new Integer(personElement.getAttribute( "id"));
Person person= new Person();
person.setId(id);
NodeList childNodes=personElement.getChildNodes();
for(int y=0;y<childNodes.getLength();y++){
if(childNodes.item(y).getNodeType()==Node.ELEMENT_NODE){
if("name" .equals(childNodes.item(y).getNodeName())){
String name=childNodes.item(y).getFirstChild().getNodeValue();
person.setName(name);
} else if("age" .equals(childNodes.item(y).getNodeName())){
String age=childNodes.item(y).getFirstChild().getNodeName();
person.setAge( new Short(age));
}
}
}
persons.add(person);
}
in.close();
return persons;
}
}
pull解析器:
public class PullParser {
public PullParser() {
// TODO Auto-generated constructor stub
}
@SuppressLint("UseValueOf" )
private List<Person> xmlParser(InputStream in) throws XmlPullParserException, IOException{
// InputStream is=this.getClass().getClassLoader().getResourceAsStream("**.xml");
Person person= null;
List<Person> persons= null;
XmlPullParser pullParser=Xml. newPullParser();
pullParser.setInput(in, "UTF-8");
int event=pullParser.getEventType();//触发第一个事件
while(event!=XmlPullParser.END_DOCUMENT){
switch(event){
case XmlPullParser.START_DOCUMENT:
persons= new ArrayList<Person>();
break;
case XmlPullParser.START_TAG:
if("person" .equals(pullParser.getName())){
int id=new Integer(pullParser.getAttributeName(0));
person= new Person();
person.setId(id);
}
if(person!=null ){
if("name" .equals(pullParser.getName())){
person.setName(pullParser.nextText());
}
if("age" .equals(pullParser.getName())){
person.setAge( new Short(pullParser.nextText()));
}
}
break;
case XmlPullParser.END_TAG:
if("person" .equals(pullParser.getName())){
persons.add(person);
person= null;
}
break;
}
event=pullParser.next();
}
return persons;
}
}
//生成xml文档----
public static void save(List<Person> persons, OutputStream out) throws Exception, IllegalStateException, IOException{
//顶一个一个接口,实现串行化--对象序列化
XmlSerializer serializer=Xml. newSerializer();
serializer.setOutput(out, "UTF-8");
serializer.startDocument( "UTF-8", true );
serializer.startTag( null, "persons" );
for(Person person:persons){
serializer.startTag( null, "person" );
serializer.attribute( null, "id" , person.getId().toString());
serializer.startTag( null, "name" );
serializer.text(person.getName());
serializer.endTag( null, "name" );
serializer.startTag( null, "age" );
serializer.text(person.getAge().toString());
serializer.endTag( null, "age" );
serializer.endTag( null, "person" );
}
serializer.endTag( null, "persons" );
serializer.endDocument();
out.flush();
out.close();
}