zoukankan      html  css  js  c++  java
  • Android开发XML解析方法


    XML:可扩展标记语言

    XML如今已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性给数据集成与交互带来了极大的方便。对于XML本身的语法知识与技术细节须要阅读相关的技术文献,这里不做详细的阐述了。

    XML称为可扩展标记语言,它与HTML一样,都是SGML(标准通用标记语言)XML是Internet环境中款平台的,依赖于内容技术,是当前处理结构画文档信息的有力工具,可扩展标记语言XML是一种简单的数据存储语言。使用一些简单的标记描写叙述数据。

    <?xml version="1.0"encoding="UTF-8"?>
    <persons>
       <person id="23">
         <name>jack</name>
         <age>30</age>
       </person>
       <person id="20">
         <name>rose</name>
         <age>25</age>
       </person>
    </persons>

    以上是简单的XML的结构,XML结构解析例如以下:

    1、节点

    2、元素

    3、属性和属性值

    XML在不同的语言里解析方式都是一样的。仅仅只是实现的语法不同而已。主要的解析方式有例如以下三种:

    1、DOM(org.w3c.dom):"文档对象模型"方式,解析完的Xml将生成一个树状结构的对象。

    2、SAX(org.xml.sax):以事件的形式通知程序,对xml进行解析。

    3、XMLPULL(org.xmlpull.v1):类似于SAX方式,程序以“拉取”的方式对XML进行解析。

    DOM解析方式:

    DOM是一种用于XML文档对象模型,可用于直接訪问XML文档的各个部位,在DOM中文档被模拟为树状。当中xml语法的每个组成部分都表示一个节点。DOM同意用户便利文档树,从父节点移动到子节点的兄弟节点。并利用某节点类型特有的属性(元素具有属性,文本节点具有文本数据)

    在DOM中,整个文档是一个节点文档。每个xml标签是一个元素节点。包括xml元素中的文本是文本节点。每个xml属性是一个属性节点。

    SAX解析方式:

    SAX是一种以时间驱动XML api,由它定义的事件流能够制定从解析器传到专门的处理程序的代码XML结构,简单的讲,它解析速度快。占用内存少。

    这样的解析器比較适合android等移动设备。

    SAX的长处:

    由于SAX的优势是流的方式处理,当遇到一个标签的时候,并不会记录下当前所碰到的标签。也就是说,startElement方法中,你所知道的信息,不过当前的签名的名字和属性,至于标签的潜逃结构,上层标签的名字。是否有子元素与其它结构相关的信息,都是不知道的。

    PULL解析方式:

    PULL解析器执行方式与sax解析器非常相似,它提供了类似的事件。如開始元素和结束元素,使用parse.next()能够进行下一个元素而且出发对应的时间,时间将作为代码被发送,因此能够使用一个switch来对时间进行选择,然后进行对应的处理,。当開始解析元素的时候,调用parser.nextText()法官法能够获得下一个Text类型的元素。


    综合以上三种解析方式,从内存的占用率来说:SX和PULL比DOM占用更少的内存解析方式,更加适合Android手机开发。

    以下,我们以SAX解析方式为例。演示SAX解析xml文件的过程:

    首先,要定义一个类用来继承DefaultHandler,之后重写startDocument,startElement,characters。EndElement方法。当中startDocument是在解析到開始文档的时候调用的方法,startElement是在解析開始元素的时候调用的,characters是在读取节点信息的时候调用。EndElement是在读取完毕的时候调用的。

    public class MyHandler extends DefaultHandler {
    	// 存储单个解析的完整对象
    	private HashMap<String, String> map = null;
    	// 存储全部解析的对象
    	private List<HashMap<String, String>> list = null;
    	// 正在解析元素的标签
    	private String currentTag = null;
    	// 解析当前元素的值
    	private String currentValue = null;
    	// 解析当前的节点名称
    	private String nodeName = null;
    
    	public MyHandler(String nodeName) {
    		// TODO Auto-generated constructor stub
    		this.nodeName = nodeName;
    	}
    
    	// 解析到開始文档的时候,触发startDocument
    	@Override
    	public void startDocument() throws SAXException {
    		// 当读到第一个開始标签的时候会触发该方法
    		list = new ArrayList<HashMap<String, String>>();
    		super.startDocument();
    	}
    
    	public List<HashMap<String, String>> getList() {
    		return list;
    	}
    
    	// 解析到開始元素
    	@Override
    	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    		// 当遇到文档开头的时候调用该方法
    		if (qName.equals(nodeName)) {
    			map = new HashMap<String, String>();
    		}
    		if (attributes != null && map != null) {
    
    			for (int i = 0; i < attributes.getLength(); i++) {
    				map.put(attributes.getQName(i), attributes.getValue(i));
    			}
    		}
    		currentTag = qName;
    		// super.startElement(uri, localName, qName, attributes);
    
    	}
    
    	// 读取文档节点内容
    	@Override
    	public void characters(char[] ch, int start, int length) throws SAXException {
    		// TODO Auto-generated method stub
    		// 这种方法是用来处理XM;文件所读取到的内容
    		if (currentTag != null && map != null) {
    			currentValue = new String(ch, start, length);
    			if (currentValue != null && !currentValue.trim().equals("") && !currentValue.trim().equals("
    ")) {
    				map.put(currentTag, currentValue);
    			}
    		}
    		// 把当前节点的相应的值和标签设置为空
    		currentTag = null;
    		currentValue = null;
    		// super.characters(ch, start, length);
    	}
    
    	// 读取文档节点内容完毕时
    	@Override
    	public void endElement(String uri, String localName, String qName) throws SAXException {
    		// TODO Auto-generated method stub
    		// 遇到结束标记的时候,调用该方法
    		if (qName.equals(nodeName)) {
    			list.add(map);
    			map = null;
    		}
    		super.endElement(uri, localName, qName);
    	}
    
    }
    

    PULL解析方法:


    针对上述的xml文件里的节点元素名称做的一个pull解析器,收先要先声明一个类用来装载person对象,该类中存在 id,name。age三个属性并分别声明get和set方法,然后编写一个从server获取xml文件的方法。获取到server中的xml文件,而且以流的形式返回:

    public class http {
    
    	public http() {
    		// TODO Auto-generated constructor stub
    	}
    	/**
    	 * 从server获取XML文件,返回一个流
    	 * @param path
    	 * @return
    	 */
    
    	public static InputStream getXML(String path) {
    		InputStream inputStream = null;
    
    		try {
    			URL url = new URL(path);
    			if (url != null) {
    				HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    				connection.setReadTimeout(3000);
    				connection.setDoInput(true);
    				connection.setRequestMethod("GET");
    				int code = connection.getResponseCode();
    				if (code == 200) {
    					inputStream = connection.getInputStream();
    				}
    			}
    
    		} catch (MalformedURLException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    
    		return inputStream;
    	}
    
    }
    
    获取到server中的xml文件后,開始使用pull方法解析xml数据了

    public class PullXmlTools {
    	//主要使用pull解析xml
    
    	public PullXmlTools() {
    		// TODO Auto-generated constructor stub
    	}
    	
    	/**
    	 * 
    	 * @param inputStream  从server获取xml文件,以流的形式返回
    	 * @param encode 编码格式 须要跟xml格式一致
    	 * @return
    	 * @throws XmlPullParserException 
    	 * @throws IOException 
    	 */
    	
    	public static List<Person> parseXML(InputStream inputStream,String encode) throws XmlPullParserException, IOException{
    		
    		List<Person> list =null;
    		//用来装载解析每个person节点的内容
    		Person person =null;
    		
    		//创建一个解析xml的工场
    		
    		XmlPullParserFactory factory =XmlPullParserFactory.newInstance();
    		//获得xml解析类的引用
    		XmlPullParser parser =factory.newPullParser();
    		parser.setInput(inputStream,encode);
    		//获得事件的类型
    		int eventType =parser.getEventType();
    		//推断是否读取到文档结束标签
    		while(eventType!=XmlPullParser.END_DOCUMENT){
    			switch (eventType){
    			
    			case XmlPullParser.START_DOCUMENT:
    				list = new ArrayList<Person>();
    				break;
    			case XmlPullParser.START_TAG:
    				if ("person".equals(parser.getName())) {
    					//取出属性值,0表示第0个属性
    					int id = Integer.parseInt(parser.getAttributeName(0));
    					person.setId(id);
    				}else if ("name".equals(parser.getName())) {
    					String name = parser.nextText();
    					person.setName(name);
    				}else if("age".equals(parser.getName())){
    					int age =Integer.parseInt(parser.nextText());
    					person.setAge(age);
    				}
    				break;
    			case XmlPullParser.END_TAG:
    				if ("person".equals(parser.getName())) {
    					list.add(person);
    					person = null;
    				}
    				break;
    			}
    			eventType =parser.next();
    		}
    		
    		
    		return list;
    		
    	}
    
    }
    
    最后,在test文件里检測一下:

    public class Test {
    
    	public Test() {
    		// TODO Auto-generated constructor stub
    	}
    
    	public static void main(String[] args) {
    		
    		String path ="http://192.168.199.247:8080/myhttp/person.xml";
    		InputStream inputStream = http.getXML(path);
    		//定义一个List用来承装解析后的数据
    		List<Person> list =null;
    		try {
    			list = PullXmlTools.parseXML(inputStream, "utf-8");
    		} catch (XmlPullParserException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
                    //使用for循环来展示list中的数据,即解析xml文件后所得的数据
    		for(Person person:list){
    			System.out.println(person.toString());
    		}
    	}
    }

    谢谢大家,请尊重作者的劳动成果,转载请附上转载链接,谢谢!


  • 相关阅读:
    实现点击预览图片更改页面背景图片的效果
    JavaScript中赋值运算符的使用
    Visual Studio常用快捷键
    循 环 嵌 套
    控制摄像头拍照
    运用<body>属性,渲染页面效果
    子查询的易错点
    随机数
    PDO获取数据乱码的解决方法
    JavaScript中比较运算符的使用
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/7152554.html
Copyright © 2011-2022 走看看