XML解析的三种方式总结
来源:互联网 发布:dota牛蛙淘宝店 编辑:程序博客网 时间:2024/05/16 09:08
XML解析有三种方式,这里来总结一下
*************************SAX*************************
首先是SAX方式,这种方式是边加载边解析
关键的一个类是DefaultHandler,我们通过集成这个类,Override一些关键的方法,从而解析XML文件
主要的方法有
@Overridepublic void startDocument() throws SAXException {list = new ArrayList<Person>();Log.i(tag,"startDocument()");}
这个方法是在开始解析文档的时候调用,通常做一下初始化的工作,然后就绪执行startElement()方法
@Overridepublic void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {......preTag = localName; }
我在startElement()方法里面解析XML标签,其中localName是当前标签的名字,attributes是存储了标签属性的数组,我们通过if语句判断是否我们需要的标签,然后提取需要的属性信息来构造Bean就可以了
这里我们使用一个preTag全局变量来存储当前标签,便于character方法的使用
然后会接着执行character()方法,我们在这个方法里面提取文本信息
@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {String content = new String(ch,start,length);.......}
这里构造出的content就是文本信息了,但是我怎么知道,这个那个标签里面的文本信息,这时就要使用到preTag,来判断是那个标签
接着会调用endElement()方法
@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {.......Log.i(tag,localName+"***end element***");preTag = null;}
这里我们有获得了localName,也就是当前标签的名字
并且我们有一个关键的操作,就是preTag=null的设置
因为xml文件里面,空白区域也被当成了节点,所以我们如果不设置pretag为空,那么preTag记录的就是上一个标签的名字,当我们解析到空白节点时,进入character()方法,就可能把远的preTag所对应的文本覆盖成空
最后调用endDocument()方法,做一些收尾的工作
@Overridepublic void endDocument() throws SAXException {Log.i(tag,"endDocument()");}
继承好DefaultHandler类以后,我就要使用
InputStream is = PersonServiceTest.class.getClassLoader().getResourceAsStream("person.xml");if(is!=null){SAXForHandler s = new SAXForHandler();SAXParserFactory pf = SAXParserFactory.newInstance();SAXParser sp = pf.newSAXParser();sp.parse(is,s);for(Person person:s.list){Log.i(Tag,person.toString());}}
使用方法很简单,首先创建一个SAX工程,然后利用工程生成一个解析器
把xml数据流,和Handler对象传入解析器就可以了
*************************DOM*************************
dom解析方式是先加载整个xml文件再解析,这样的好处是,我们知道了DOM树的结构,和节点之间的关系,不利之处是要加载整个文件,解析速度慢
解析方式如下,首先创建一个DOMbulider工程,然后生产一个DOMbulider,把xml数据流传入DOMbulider.parse(),就可以生成一个DOMCUMENT对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = factory.newDocumentBuilder();Document document = builder.parse(inStream);
下面的解析过程就比较难说清楚了,首先是获取文件根节点
Element root = document.getDocumentElement();
然后根据文件根节点,获取所有Node
NodeList personNodes = root.getElementsByTagName("person");
这里要说明一下node跟Elment,我们主要使用element来获取标签的相关信息,不过首先我们要使用Node转换成Element
我们通过一个循环,来遍历所有的Person,用node.item()来获取,对于每一个node,我们在强制转换成Element
for(int i=0;i<personNodes.getLength();i++){Element personElement = (Element) personNodes.item(i);.....}
有了element对象,我就可以获取它的属性
int id = new Integer(personElement.getAttribute("id"));
接着像根节点一样,获取该element的所有子节点
NodeList childNodes = personElement.getChildNodes();for(int y=0;y<childNodes.getLength();y++){.....}不断地按照这个方式,就能完整构造出bean对象
*************************PULL*************************
PULL方法,可以说结合了上面两种方法解析便利上的优点,并且它表示通过工厂创建的,而是直接创建,但是接下来把xml流传进去解析,也是一样的步骤
XmlPullParser pullParser = Xml.newPullParser();pullParser.setInput(inStream,"UTF-8");
下面的解析全都围绕着pullParser这个对象进行了
首先一个方法是getEventType()获取当前节点的类型,注意每次pullParser都表示当前正在解析的节点,只有调用它的next()方法,才会移到下一个节点,类似cursor
判断节点类型后,不是END_DOCUEMNT,我们就一直解析(next())
接着几个属性就是XmlPullParser.START_DOCUMENT,XmlPullParser.START_TAG,XmlPullParser.END_TAG
根据不同类型解析就可以了
pullParser.getName()获得标签名字
pullParser.getAttributeValue(0)获得标签属性
pullParser.nextText()获得标签文本
调用上面的几个方法,勾构造bean就可以了
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.getAttributeValue(0));person = new Person();person.setId(id);}if(person!=null){if("name".equals(pullParser.getName())){person.setName(pullParser.getAttributeValue(0));}if("age".equals(pullParser.getName())){person.setAge(new Short(pullParser.nextText()));}if("ddd".equals(pullParser.getName())){person.setDdd(pullParser.nextText());}}break;case XmlPullParser.END_TAG:if("person".equals(pullParser.getName())){persons.add(person);person = null;}}event = pullParser.next();}
说过XML的解析,我顺便说一下xml文件的构造,这种构造方法,跟pull解析的方式很类似,就是刚好反过来
首先获取一个序列化构造对象,设置输出流
然后startDocument()方法,就可以开始构造文件根节点
然后startTag()就可以设置一个标签
attribute()就设置这个标签的属性
text()就可以设置文本
endTag()就可以闭合标签
其中startTag相互嵌套,就可以构成树状结构
最好endDocument()就可以关闭root了
XmlSerializer serializer = Xml.newSerializer();serializer.setOutput(outStream, "UTF-8");serializer.startDocument("UTF-8", true);serializer.startTag(null, "persons");for (Person person : persons) {serializer.startTag(null, "person");serializer.attribute(null, "id", "1");serializer.startTag(null, "name");serializer.text("zhangsan");serializer.endTag(null, "name");}serializer.endTag(null, "persons");serializer.endDocument();outStream.flush();outStream.close();
- XML解析的三种方式总结
- Java解析Xml的三种方式总结
- XML解析的三种方式
- XML三种常用的解析方式
- xml文件解析的三种方式
- XML的三种解析方式
- xml文件解析的三种方式
- Android解析XML的三种方式
- 解析xml的三种方式
- xml的三种解析方式
- android 解析xml的三种方式
- Android 解析xml的三种方式
- Java解析XML的三种方式
- XML解析的三种方式
- XML的三种解析方式
- Xml数据解析的三种方式
- Android解析XML的三种方式
- XML解析的三种方式
- Linux常用命令
- [Leetcode]String to Integer (atoi)
- Spring 事务隔离级别
- 工作过程中学到的正则表达式
- C语言中Uint8_t数据类型
- XML解析的三种方式总结
- ios调用dismissViewController的一个小陷阱
- 【cocos2dx网络游戏】搭建CS架构的基本通信框架(一)server
- NSArray 和 NSMutableArray 定义和基本用法
- Download interrupted: URL not found.
- Redis的安装、配置
- Android监听外部存储设备的状态(SD卡、U盘等等)
- json_ajax交互
- poj 1041 John's trip 欧拉回路