安卓实训第十一天--DOM、SAX解析XML
2014-06-03 22:15
344 查看
今天我们首先讲了运用DOM方法来解析XML,实现天气预报的显示还有城市间的切换功能:
DOM功能类的实现代码如下:
MainActicity,安卓方面的操作的实现:
<!--
节点名称 节点值 节点值 类型值
元素节点: 标签名 null 1
属性节点: 属性名 属性值 2
文本节点: #text 文本内容 3
-->
然后我们用第二种方法来解析XML,那就是利用SAX工厂模式:
SAX功能类的实现:
然后是MainActivity关于安卓方面的实现:
补充知识:
SAX 是用于处理XML时间驱动的推模型来进行操作,最大的优点是内存消耗较小,因为整个文档无需一次加载到内存中,这种SAX解析可以解析大于系统内存的文档。
缺点是:不能直接获取一个标签内的内容,必须从头到尾解析一遍。文档越复杂, 你的逻辑就越复杂。
SAX解析中用到了DefaultHandler实现了以下的接口:用于访问XML:DtdHandler,用于低级访问解析错误的:ErrorHandler,用于访问文档内容的:ContentHandler
DOM解析与SAX解析的区别:
1、dom的优点:易用性强,使用DOM时,将把所有的XML文档信息都存于内存中,并且遍历简单,支持XPath,增强了易用性。
2、dom的缺点:效率地,解析速度慢,内存占用量过高,对于大文件来说几乎不可能,另外效率低还表现在大量的消耗时间。
区别:1、把所有的XML文档信息都存于内存中。
2、SAX无需一次把XML文件加载到内存中,采用的是事件驱动的操作。
3、应用场景不一样,DOM只能用于小文件,SAX可以应用在大文件上
4、DOM可以直接获取某个结点,但是SAX则不行。
DOM功能类的实现代码如下:
package com.example.example; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class DOMXML { public List<City> domXml() { // 创建返回的集合对象 List<City> cities = new ArrayList<City>(); // 创建了文档解析器的工厂对象 DocumentBuilderFactory builderFactory = DocumentBuilderFactory .newInstance(); try { // 得到文档解析器对象 DocumentBuilder builder = builderFactory.newDocumentBuilder(); // 获取输入流对象 InputStream is = getClass().getClassLoader().getResourceAsStream( "china.xml"); // 通过解析器的parse方法解析is对象,转换成Document对象 Document document = builder.parse(is); //返回的是文档的根节点 Element rootElement = document.getDocumentElement(); // 判断它是否有孩子节点 if (rootElement.hasChildNodes()) { // 获取所有子节点 NodeList nodeList = rootElement.getChildNodes(); System.out.println("子节点的长度是:" + nodeList.getLength()); // 遍历子节点 for (int i = 0; i < nodeList.getLength(); i++) { // 获取子节点对象 Node node = nodeList.item(i); // 判断这个子节点是什么类型的子节点,文本节点 if (node.getNodeType() == Element.ELEMENT_NODE) { // 获取元素节点的属性节点 // 转换成元素节点 // 创建一个实体对象,保存元素节点的值: City city = new City(); // 造型 Element element = (Element) node; cities.add(new City(element.getAttribute("cityName"), element.getAttribute("pyName"), element .getAttribute("quName"), element .getAttribute("state1"), element .getAttribute("state2"), element .getAttribute("stateDetailed"), element .getAttribute("tem1"), element .getAttribute("tem2"), element .getAttribute("windState"))); } } } } catch (Exception e) { e.printStackTrace(); } return cities; } /* //前一种方法:不好用 public List<City> domXml1() { // 创建返回的集合对象 List<City> cities = new ArrayList<City>(); // 创建了文档解析器的工厂对象 DocumentBuilderFactory builderFactory = DocumentBuilderFactory .newInstance(); try { // 得到文档解析器对象 DocumentBuilder builder = builderFactory.newDocumentBuilder(); // 获取输入流对象 InputStream is = getClass().getClassLoader().getResourceAsStream( "china.xml"); // 通过解析器的parse方法解析is对象,转换成Document对象 Document document = builder.parse(is); Element rootElement = document.getDocumentElement(); // 判断它是否有孩子节点 if (rootElement.hasChildNodes()) { // 获取所有子节点 NodeList nodeList = rootElement.getChildNodes(); System.out.println("子节点的长度是:" + nodeList.getLength()); // 遍历子节点 for (int i = 0; i < nodeList.getLength(); i++) { // 获取子节点对象 Node node = nodeList.item(i); * System.out.println(node.getNodeType() + "------" + * Element * .DOCUMENT_TYPE_NODE+"------------"+Element.ELEMENT_NODE * +"---------"); // 判断这个子节点是什么类型的子节点,文本节点 if (node.getNodeType() == Element.ELEMENT_NODE) { // 获取元素节点的属性节点 // 转换成元素节点 // 创建一个实体对象,保存元素节点的值: City city = new City(); // 造型 Element element = (Element) node; // 得到这个节点中的所有属性 NamedNodeMap map = element.getAttributes(); // 遍历属性节点 for (int j = 0; j < map.getLength(); j++) { // 获取具体的某个属性节点 Attr attr = (Attr) map.item(j); // 具体判断,属性节点只能这样做 if ("cityname".equals(attr.getNodeName())) { city.setCityName(attr.getNodeValue()); } else if ("pyName".equals(attr.getNodeName())) { city.setPyName(attr.getNodeValue()); } else if ("quName".equals(attr.getNodeName())) { city.setQuName(attr.getNodeValue()); } else if ("state1".equals(attr.getNodeName())) { city.setState1(attr.getNodeValue()); } else if ("state2".equals(attr.getNodeName())) { city.setState2(attr.getNodeValue()); } else if ("stateDetailed".equals(attr .getNodeName())) { city.setStateDetailed(attr.getNodeValue()); } else if ("windState".equals(attr.getNodeName())) { city.setWindState(attr.getNodeValue()); } // 获取属性值和属性名 // System.out.println("属性名:" + attr.getName() + // "属性值" // + attr.getValue()); } cities.add(city); // // 是否还有子节点 // if (node.hasChildNodes()) { // // 获取所有的子节点 // NodeList list1 = node.getChildNodes(); // // 遍历 // for (int k = 0; k < list1.getLength(); k++) { // // 获取子节点 // Node nk = list1.item(k); // // 判断是否是元素节点 // if (nk.getNodeType() == Element.ELEMENT_NODE) { // System.out.println("节点名称:" // + nk.getNodeName() + "节点值:" // + nk.getFirstChild().getNodeValue()); // } // } // } } } } } catch (Exception e) { e.printStackTrace(); } return cities; }*/ }
MainActicity,安卓方面的操作的实现:
package com.example.example; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.widget.RadioGroup; import android.widget.RadioGroup.OnCheckedChangeListener; import android.widget.TextView; public class MainActivity extends Activity implements OnCheckedChangeListener{ //初始化标签 private RadioGroup rg; private TextView tv_wendu,tv_fengli; private DOMXML domxml; private List<City> cities; private int checkedId=1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); rg = (RadioGroup) findViewById(R.id.rg); rg.setOnCheckedChangeListener(this); tv_wendu = (TextView) findViewById(R.id.tv_wendu); tv_fengli =(TextView) findViewById(R.id.tv_fengli); //解析xml文件 domxml = new DOMXML(); cities = domxml.domXml(); //获取被选中的控件的ID值 checkedId = rg.getCheckedRadioButtonId(); initData(checkedId); } @Override public void onCheckedChanged(RadioGroup group, int checkedId) { initData(checkedId); } private void initData(int checkedId) { City city = null; //System.out.println(checkedId+"---------------"+R.id.radio1); switch (checkedId) { case R.id.radio0: //北京天气: for(City c:cities){ if("北京".equals(c.getCityName())){ city=c; } } break; case R.id.radio1: for(City c:cities){ if("南京".equals(c.getCityName())){ city=c; } } break; case R.id.radio2: for(City c:cities){ if("连云港".equals(c.getCityName())){ city=c; } } break; } if(city!=null){ tv_wendu.setText(city.getTem2()+"°~"+city.getTem1()+"°"); tv_fengli.setText(city.getWindState()); } } }
<!--
节点名称 节点值 节点值 类型值
元素节点: 标签名 null 1
属性节点: 属性名 属性值 2
文本节点: #text 文本内容 3
-->
然后我们用第二种方法来解析XML,那就是利用SAX工厂模式:
SAX功能类的实现:
package com.example.example; 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; public class SaxXML { public List<City> saxXML() { MyDefaultHandler myHandler = new MyDefaultHandler(); // 第一步:创建解析器工厂 SAXParserFactory spf = SAXParserFactory.newInstance(); try { // 第二步:使用单签配置的工厂参数穿件SAXParser的一个新实例 SAXParser saxParser = spf.newSAXParser(); saxParser.parse( getClass().getClassLoader() .getResourceAsStream("china.xml"), myHandler); } catch (Exception e) { e.printStackTrace(); } return myHandler.cities; } class MyDefaultHandler extends DefaultHandler { private String tagName=null;//当前解析的标签 private City currentCity = null; private List<City> cities;//当前解析的对象 public List<City> getCities() { return cities; } @Override public void startDocument() throws SAXException { super.startDocument(); //System.out.println("---------startDocument()-----------"); //实例化 cities = new ArrayList<City>(); } @Override public void endDocument() throws SAXException { super.endDocument(); System.out.println("---------endDocument()-----------"); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); // System.out.println("---------startElement()-----------"+uri+localName+qName+attributes); //判断是不是CITY标签 if (qName.equals("city")) { //实例化对象 currentCity = new City(); //判断属性对象是否为NULL if (attributes != null) { //如果不为NULL,就获取属性值,并且复制到CITY对象中 currentCity.setCityName(attributes.getValue("cityName")); currentCity.setPyName(attributes.getValue("pyName")); currentCity.setQuName(attributes.getValue("quName")); currentCity.setState1(attributes.getValue("state1")); currentCity.setState2(attributes.getValue("state2")); currentCity.setStateDetailed(attributes .getValue("stateDetailed")); currentCity.setTem1(attributes.getValue("tem1")); currentCity.setTem2(attributes.getValue("tem2")); currentCity.setWindState(attributes.getValue("windState")); } } /* * int length = attributes.getLength(); for(int * index=0;index<length;index++){ * String attrQName = attributes.getQName(index); * String attrValue =attributes.getValue(attrQName); * Sysout.out.println(attrQName+"------------"+attrValue); * } */ this.tagName = qName; } @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); // System.out.println("-----------endElement()---------------"+uri+localName+qName); if (qName.equals("city")) { cities.add(currentCity); currentCity = null; } this.tagName = null; } @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); if (tagName != null) { String value = new String(ch, start, length); if (tagName.equals("name")) { // System.out.println("------characters()-------"+new // String(ch, start,length)); currentCity.setCityName(value); }else if(tagName.equals("pyName")){ currentCity.setPyName(value); }else if(tagName.equals("quName")){ currentCity.setQuName(value); }else if(tagName.equals("state1")){ currentCity.setState1(value); }else if(tagName.equals("state2")){ currentCity.setState2(value); }else if(tagName.equals("stateDetailed")){ currentCity.setStateDetailed(value); }else if(tagName.equals("tem1")){ currentCity.setTem1(value); }else if(tagName.equals("tem2")){ currentCity.setTem2(value); }else if(tagName.equals("windState")){ currentCity.setWindState(value); } } } } }
然后是MainActivity关于安卓方面的实现:
package com.example.example; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity implements OnItemSelectedListener{ private Spinner sp_cities; private String cities[]; private SaxXML saxXML; private TextView tv_fengli; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sp_cities = (Spinner) findViewById(R.id.sp_city); tv_fengli = (TextView) findViewById(R.id.tv_fengli); //注册时间 sp_cities.setOnItemSelectedListener(this); cities=getResources().getStringArray(R.array.cities); sp_cities.setSelection(2); saxXML = new SaxXML(); } @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { System.out.println(parent+"---"+view+"---"+position+"---"+id); Toast.makeText(this, cities[position], Toast.LENGTH_LONG).show(); List<City> entities = saxXML.saxXML(); for(City c:entities){ if(c.getQuName().equals(cities[position])){ tv_fengli.setText(c.getWindState()); break; } } } @Override public void onNothingSelected(AdapterView<?> arg0) { System.out.println("没选择"); } }
补充知识:
SAX 是用于处理XML时间驱动的推模型来进行操作,最大的优点是内存消耗较小,因为整个文档无需一次加载到内存中,这种SAX解析可以解析大于系统内存的文档。
缺点是:不能直接获取一个标签内的内容,必须从头到尾解析一遍。文档越复杂, 你的逻辑就越复杂。
SAX解析中用到了DefaultHandler实现了以下的接口:用于访问XML:DtdHandler,用于低级访问解析错误的:ErrorHandler,用于访问文档内容的:ContentHandler
DOM解析与SAX解析的区别:
1、dom的优点:易用性强,使用DOM时,将把所有的XML文档信息都存于内存中,并且遍历简单,支持XPath,增强了易用性。
2、dom的缺点:效率地,解析速度慢,内存占用量过高,对于大文件来说几乎不可能,另外效率低还表现在大量的消耗时间。
区别:1、把所有的XML文档信息都存于内存中。
2、SAX无需一次把XML文件加载到内存中,采用的是事件驱动的操作。
3、应用场景不一样,DOM只能用于小文件,SAX可以应用在大文件上
4、DOM可以直接获取某个结点,但是SAX则不行。
相关文章推荐
- 经典面试题:一张表区别DOM解析和SAX解析XML
- 安卓解析XML文件系列3:使用DOM方式
- 疯狂安卓实训 第13.2.3讲 HTTPClient的简易用法
- MiniDB实训第十一天
- 经典面试题:一张表区别DOM解析和SAX解析XML
- 安卓实训第十二天---xml解析PULL解析的实现,安卓测试,logcat的使用方法
- <实训|第十一天>学习一下linux中的进程,文件查找,文件压缩与IO重定向
- 疯狂安卓实训 第13.2.4讲 HTTPClient的高级功能
- Dom,pull,Sax解析XML
- 疯狂安卓实训 第13.2.2讲 使用HttpURLConnection访问网络资源
- 安卓实训笔记第二天
- 安卓实训第七天---多线程下载实现(进度条)
- dom生成的结点在安卓手机在中点击事件有效,但在苹果手机中点击事件失效
- 安卓实训教程第一天:搭建环境,并且运行第一个helloworld以及电话拨号器
- 安卓实训第十二天(补充部分)---Sqlite数据库的创建和改变,以及使用SQLiteDataBase完成CRUD操作
- 安卓实训第十四天---使用ContentProvider共享数据,并且利用ContentResolver监听共享数据
- 疯狂安卓实训 第13.2.1讲 使用URL和URLConnection访问网络资源
- web day6 DOM&XML(JAXP的SAX解析XML,schema入门,dom4j&XPath的增删改查)
- java学习笔记——使用DOM解析XML和使用SAX解析XML
- 安卓实训第十三天---SQLITE中的事务操作以及方法的复习