前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布

4.XML

作者头像
六月的雨
发布2018-05-14 10:08:54
7030
发布2018-05-14 10:08:54
举报
文章被收录于专栏:Android开发指南

4.XML

代码语言:javascript
复制
使用XMl序列化器生成xml文件

//1.拿到序列化器对象
 XmlSerializer xs = Xml.newSerializer();
 //2.初始化
 File file = new File("sdcard/sms2.xml");
 try {
 FileOutputStream fos = new FileOutputStream(file);
 //enconding:指定用什么编码生成xml文件
			xs.setOutput(fos, "utf-8");
 //3.开始生成xml文件
 //enconding:指定头结点中的enconding属性的值
			xs.startDocument("utf-8", true);
			xs.startTag(null, "message");
 for (Message sms : smsList) {
				xs.startTag(null, "sms");
				xs.startTag(null, "body");
				xs.text(sms.getBody() + "<body>");
				xs.endTag(null, "body");
				xs.startTag(null, "date");
				xs.text(sms.getDate());
				xs.endTag(null, "date");
				xs.startTag(null, "type");
				xs.text(sms.getType());
				xs.endTag(null, "type");
				xs.startTag(null, "address");
				xs.text(sms.getAddress());
				xs.endTag(null, "address");
				xs.endTag(null, "sms");
 }
			xs.endTag(null, "message");
 //告诉序列化器,文件生成完毕
			xs.endDocument();
 } catch (Exception e) {
 // TODO Auto-generated catch block
			e.printStackTrace();
 } 

pull解析xml文件

代码语言:javascript
复制
先自己写一个xml文件,存一些天气信息
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<weather>
 <city>
 <name>上海</name>
 <temp>5°</temp>
 <pm>80</pm>
 </city>
 <city>
 <name>北京</name>
 <temp>-5°</temp>
 <pm>800</pm>
 </city>
 <city>
 <name>西安</name>
 <temp>12°</temp>
 <pm>60</pm>
 </city>
</weather>
代码语言:javascript
复制
public void click(View v){
 //获取到src文件夹下的资源文件
 InputStream is = getClassLoader().getResourceAsStream("weather.xml");
 //拿到pull解析器对象,和xml序列化器方法一样
 XmlPullParser xp = Xml.newPullParser();
  1. 也可以这样或得pull解析器: 首先要获取到一个XmlPullParserFactory 的实例,并借助这个实例得到 XmlPullParser 对象,然后调用XmlPullParser的 setInput()方法将服务器返回的 XML数据设置进去就可以开始解析
代码语言:javascript
复制
//XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
//XmlPullParser xmlPullParser = factory.newPullParser();
//xmlPullParser.setInput(new StringReader(xmlData));		
//初始化		
try {			xp.setInput(is, "gbk");

上面的xml解析是通过传入的InputStream来进行解析、也可以通过直接解析String、要想直接解析String、可将上面传参改为String类型并将parser.setInput(inputStream,encoding);改为parser.setInput(new StringReader(string));便可以直接解析字符串形式的xml文件

代码语言:javascript
复制
 //获取当前节点的事件类型,通过事件类型的判断,我们可以知道当前节点是什么节点,从而确定我们应该做什么操作

 int type = xp.getEventType();
 City city = null;
 while(type != XmlPullParser.END_DOCUMENT){
 //根据节点的类型,要做不同的操作
 switch (type) {
 case XmlPullParser.START_TAG:
 //					获取当前节点的名字
 if("weather".equals(xp.getName())){
 //创建city集合对象,用于存放city的javabean
						cityList = new ArrayList<City>();
 }
 else if("city".equals(xp.getName())){
 //创建city的javabean对象
						city = new City();
 }
 else if("name".equals(xp.getName())){
 //				获取当前节点的下一个节点的文本
 String name = xp.nextText();
						city.setName(name);
 }
 else if("temp".equals(xp.getName())){
 //				获取当前节点的下一个节点的文本
 String temp = xp.nextText();
						city.setTemp(temp);
 }
 else if("pm".equals(xp.getName())){
 //				获取当前节点的下一个节点的文本
 String pm = xp.nextText();
						city.setPm(pm);
 }
 break;
 case XmlPullParser.END_TAG:
 if("city".equals(xp.getName())){
 //把city的javabean放入集合中
						cityList.add(city);
 }
 break;
 }
 //把指针移动到下一个节点,并返回该节点的事件类型
				type = xp.next();
 }
 for (City c : cityList) {
 System.out.println(c.toString());
 }
 } catch (Exception e) {
 // TODO Auto-generated catch block
			e.printStackTrace();
 }
 }

SAX解析

  • 事件类型主要有五种
    • startDocument:xml头的事件类型,在这里创建节点里的各个参数的bulid
    • startElement:xml的某个节点,在定义个变量来记录当前节点的名字
    • characters:开始节点的事件类型,如果当前节点等于各个参数的话加入build
    • endElement:结束节点的事件类型,在这里已经解析出来了,可以打印看
    • endDocument:xml尾的事件类型
代码语言:javascript
复制
<apps slick-umid="3">
 <app>
 <id>1</id>
 <name>google maps</name>
 <veision>1.0</veision>
 </app>
 <app>
 <id>2</id>
 <name>chrome</name>
 <veision>2.1</veision>
 </app>
 <app>
 <id>3</id>
 <name>google play</name>
 <veision>3.0</veision>
 </app>
</apps>

Pull解析方式虽然非常的好用,但它并不是唯一的选择。SAX解析也是一种特别常用 的 XML解析方式,虽然它的用法比 Pull解析要复杂一些,但在语义方面会更加的清楚。 通常情况下都会新建一个类继承自 DefaultHandler,并重写父类的五个方法,如下

代码语言:javascript
复制
public class ContentHandler extends DefaultHandler
{
 private String nodeName;
 private StringBuilder id;
 private StringBuilder name;
 private StringBuilder version;
 @Override
 //开始 XML解析的时候调用
 public void startDocument() throws SAXException {
 //首先给id、name和version结点分别定义了一个StringBuilder对象,并在startDocument()方法里对它们进行了初始化
		id = new StringBuilder();
		name = new StringBuilder();
		version = new StringBuilder();
 }
 @Override
 public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException{
 //每当开始解析某个结点的时候,startElement()方法就会得到调用,其中localName参数记录着当前结点的名字,这里把它记录下来
		nodeName = localName;
 }
 @Override
 public void characters(char[] ch, int start, int length) throws SAXException {
 //在解析结点中具体内容的时候就会调用characters()方法,根据当前的结点名进行判断,
 //将解析出的内容添加到哪一个StringBuilder对象中
 if ("id".equals(nodeName)) {
			id.append(ch, start, length);
 }
 else if ("name".equals(nodeName)) {
			name.append(ch, start, length);
 } 
 else if ("version".equals(nodeName)) {
			version.append(ch, start, length);
 }
 }
 @Override
 public void endElement(String uri, String localName, String qName) throws SAXException {
 //在endElement()方法中进行判断,如果app结点已经解析完成,就打印出id、name和version的内容。
 //需要注意的是,目前id、name和version中都可能是包括回车或换行符的,因此在打印之前还需要调用一下trim()方法
 if ("app".equals(localName)) {
 Log.d("ContentHandler", "id is " + id.toString().trim());
 Log.d("ContentHandler", "name is " + name.toString().trim());
 Log.d("ContentHandler", "version is " + version.toString().trim());
 // 最后要将StringBuilder清空掉,,不然的话会影响下一次内容的读取。
				id.setLength(0);
				name.setLength(0);
				version.setLength(0);
 }
 }
 @Override
 public void endDocument() throws SAXException {
 }
}
代码语言:javascript
复制

private void parseXMLWithSAX(String xmlData) {// xmlData
 try {
 //创建了一个SAXParserFactory的对象
 SAXParserFactory factory = SAXParserFactory.newInstance();
 //获取到XMLReader对象
 XMLReader xmlReader = factory.newSAXParser().getXMLReader();
 ContentHandler handler = new ContentHandler();
 // 将ContentHandler的实例设置到XMLReader中
			xmlReader.setContentHandler(handler);
 // 开始执行解析
			xmlReader.parse(new InputSource(new StringReader(xmlData)));
 } 
 catch (Exception e) {
			e.printStackTrace();
 }
 }

书上的方法

代码语言:javascript
复制
public class ContentHandler extends DefaultHandler {
 private String nodeName;
 private StringBuilder id;
 private StringBuilder mp3Name;
 private StringBuilder mp3Size;
 private StringBuilder lrcName;
 private StringBuilder lrcSize;
 // 开始 XML解析的时候调用
 public void startDocument() throws SAXException {
 // 首先给结点分别定义了一个StringBuilder对象,并在startDocument()方法里对它们进行了初始化
		id = new StringBuilder();
		mp3Name = new StringBuilder();
		mp3Size = new StringBuilder();
		lrcName = new StringBuilder();
		lrcSize = new StringBuilder();
 }
 @Override
 public void startElement(String uri, String localName, String qName,
			org.xml.sax.Attributes attributes) throws SAXException {
 // 每当开始解析某个结点的时候,startElement()方法就会得到调用,其中localName参数记录着当前结点的名字,这里把它记录下来
 // TODO Auto-generated method stub
 super.startElement(uri, localName, qName, attributes);
		nodeName = localName;
 }
 @Override
 public void characters(char[] ch, int start, int length)
 throws SAXException {
 // 在解析结点中具体内容的时候就会调用characters()方法,根据当前的结点名进行判断,
 // 将解析出的内容添加到哪一个StringBuilder对象中
 if ("id".equals(nodeName)) {
			id.append(ch, start, length);
 } else if ("mp3Name".equals(nodeName)) {
			mp3Name.append(ch, start, length);
 } else if ("mp3Size".equals(nodeName)) {
			mp3Size.append(ch, start, length);
 } else if ("lrcName".equals(nodeName)) {
			lrcName.append(ch, start, length);
 } else if ("lrcSize".equals(nodeName)) {
			lrcSize.append(ch, start, length);
 }
 }
 @Override
 public void endElement(String uri, String localName, String qName)
 throws SAXException {
 // 在endElement()方法中进行判断,如果app结点已经解析完成,就打印出节点的内容。
 // 需要注意的是,目前节点中都可能是包括回车或换行符的,因此在打印之前还需要调用一下trim()方法
 if ("resource".equals(localName)) {
 Log.d("ContentHandler", "id is " + id.toString().trim());
 Log.d("ContentHandler", "mp3Name is " + mp3Name.toString().trim());
 Log.d("ContentHandler", "mp3Size is " + mp3Size.toString().trim());
 // 最后要将StringBuilder清空掉,,不然的话会影响下一次内容的读取。
			id.setLength(0);
			mp3Name.setLength(0);
			mp3Size.setLength(0);
			lrcName.setLength(0);
			lrcName.setLength(0);
 }
 }
 @Override
 public void endDocument() throws SAXException {
 }
}

视频的方法

代码语言:javascript
复制
public class Mp3ListContentHandler extends DefaultHandler {
 private List<Mp3Info> infos = null;
 private Mp3Info mp3Info = null;
 private String tagName = null;
 public Mp3ListContentHandler(List<Mp3Info> infos) {
 super();
 this.infos = infos;
 }
 public List<Mp3Info> getInfos() {
 return infos;
 }
 public void setInfos(List<Mp3Info> infos) {
 this.infos = infos;
 }
 @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);
 this.tagName = localName;
 if (tagName.equals("resource")) {
			mp3Info = new Mp3Info();
 }
 }
 @Override
 public void characters(char[] ch, int start, int length)
 throws SAXException {
 String temp = new String(ch, start, length);
 if (tagName.equals("id")) {
			mp3Info.setId(temp);
 } else if (tagName.equals("mp3.name")) {
			mp3Info.setMp3Name(temp);
 } else if (tagName.equals("mp3.size")) {
			mp3Info.setMp3Size(temp);
 } else if (tagName.equals("lrc.name")) {
			mp3Info.setLrcName(temp);
 } else if (tagName.equals("lrc.size")) {
			mp3Info.setLrcSize(temp);
 }
 super.characters(ch, start, length);
 }
 @Override
 public void endElement(String uri, String localName, String qName)
 throws SAXException {
 // TODO Auto-generated method stub
 super.endElement(uri, localName, qName);
 if (qName.equals("resource")) {
			infos.add(mp3Info);
 }
		tagName = "";
 }
 @Override
 public void startDocument() throws SAXException {
 // TODO Auto-generated method stub
 super.startDocument();
 }
 @Override
 public void endDocument() throws SAXException {
 // TODO Auto-generated method stub
 super.endDocument();
 }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-10-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 4.XML
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档