• [置顶] Android开发之XML文件的解析


    Android系统开发之XML文件的解析

           我们知道Http在网络传输中的数据组织方式有三种分别为:XML方式、HTML方式、JSON方式。其中XML为可扩展标记语言,如下:

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


        Android中解析XML数据有三种方式:分别为 DOM、SAX、和XMLPULL。下面我们分别介绍这三种方式:

    1)SAX(org.xml.sax) 方式

    Simple API for XML,以事件的形式通知程序,对XML进行解析。SAX是一种以事件驱动的XML api,由他定义的事件流可以指定从解析器传到专门的处理程序的代码的XML结构,特点是:解析速度快,占用内存少。

    代码流程:
    1) 定义一个类继承于DefaultHandler,重写其startDocument、startElement、endDocument、endElement、characters三个方法。

    public class MySaxHandler extends DefaultHandler {
    
    	private HashMap<String, String> map = null;	// 存储单个解析的完整对象
    	private List<HashMap<String, String>> list = null;	// 存储所有的解析对象
    	
    	private String currentTag = null;	// 正在解析的元素的标签
    	private String currentValues = null;	// 解析当前元素的值	
    	private String nodeName = null;			// 解析当前的节点名称
    	
    	public MySaxHandler(String nodeName) {
    		// TODO Auto-generated constructor stub
    		this.nodeName = nodeName;
    	}
    
    	/**
    	 * @return the list
    	 */
    	public List<HashMap<String, String>> getList() {
    		return list;
    	}
    	
    	@Override
    	public void startDocument() throws SAXException {
    		// 当读到第一个开始标签的时候触发
    		list = new ArrayList<HashMap<String,String>>();
    	}
    	
    	@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;
    	}
    	
    	@Override
    	public void endDocument() throws SAXException {
    		// TODO Auto-generated method stub
    		super.endDocument();
    	}
    	
    	@Override
    	public void endElement(String uri, String localName, String qName)
    			throws SAXException {
    		// 遇到结束标记的时候调用
    		if(qName.equals(nodeName)) {
    			list.add(map);
    			map = null;
    		}
    	}
    	
    	@Override
    	public void characters(char[] ch, int start, int length)
    			throws SAXException {
    		// 处理XML文件所读取到的内容
    		if(currentTag != null && map != null) {
    			currentValues = new String(ch, start, length);
    			if(currentValues != null && !currentValues.trim().equals("") && 
    					!currentValues.trim().equals("
    ")) {
    				map.put(currentTag, currentValues);
    			}
    		}
    		currentTag = null;	// 当前节点对应的值和标签设置为空
    		currentValues = null;
    	}
    }


    2) 定义一个处理流的类SaxService,调用SAXParserFactory创建一个SAXParser从输入流解析XML文件。

    public class SaxService {
    
    	public static List<HashMap<String, String>> readXml(
    			InputStream inputStream, String nodeName) {
    		try {
    			// 创建一个解析XML的工厂对象
    			SAXParserFactory spFactory = SAXParserFactory.newInstance();
    			SAXParser parser = spFactory.newSAXParser();
    			MySaxHandler handler = new MySaxHandler(nodeName);
    			parser.parse(inputStream, handler);
    			inputStream.close();
    			return handler.getList();
    
    		} catch (Exception e) {
    			// TODO: handle exception
    		}
    		return null;
    	}
    
    	public SaxService() {
    	}
    }

    3) 定义一个测试类Test,读取文件FileInputStream调用SaxService.readXml()处理。

    public class Test {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		try {
    			File file = new File("C://test.xml");
    			if(file.exists()) {
    				FileInputStream inputStream = new FileInputStream(file);
    				List<HashMap<String, String>> list = SaxService.readXml(inputStream, "person");
    				for(HashMap<String, String> map : list) {
    					System.out.println(map.toString());
    				}
    			} else {
    				System.out.println("file is not exitst");
    			}
    			
    		} catch (Exception e) {
    			// TODO: handle exception
    		}
    	}
    }


    2)DOM方式

            DOM是一种用于XML文档对象模型,可用于直接访问XML文档的各个部位,在DOM中文档被模拟为树桩
    其中XML语法的每一个组成部分都表示一个节点,DOM允许用户遍历文档树,从父节点到子节点
    和兄弟节点,并利用某节点类型特有的属性。

    节点类型:
           整个文档是一个节点文档,每个xml标签是一个元素节点,包含在XML元素中的文本是文本节点每个XML属性是一个属性节点。

    public class DomXml {
    
    	public DomXml() {
    		// TODO Auto-generated constructor stub
    	}
    
    	public List<Person> getPersons(InputStream inputStream) throws Exception {
    		List<Person> list = new ArrayList<Person>();
    		// 创建一个document解析的工厂
    		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    		DocumentBuilder builder = factory.newDocumentBuilder();
    		Document document = builder.parse(inputStream);
    		Element element = document.getDocumentElement();
    		NodeList personNodeList = element.getElementsByTagName("person");
    		for(int i = 0; i < personNodeList.getLength(); i++) {
    			Element personElement = (Element)personNodeList.item(i);
    			Person person = new Person();
    			person.setId(Integer.parseInt(personElement.getAttribute("id")));
    			NodeList childNodes = personElement.getChildNodes();
    			for(int j = 0; j < childNodes.getLength(); j++) {
    				if(childNodes.item(j).getNodeType() == Node.ELEMENT_NODE) {
    					if("name".equals(childNodes.item(j).getNodeName())) {
    						person.setName(childNodes.item(j).getFirstChild().getNodeValue());
    					} else if("age".equals(childNodes.item(j).getNodeName())) {
    						person.setAge(Integer.parseInt(childNodes.item(j).getFirstChild().getNodeValue()));
    					}
    				}
    			}
    			list.add(person);
    		}
    		return list;
    	}
    	
    	public static void main(String[] args) throws Exception {
    		
    		FileInputStream inputStream = new FileInputStream("C://test.xml");
    		DomXml domXml = new DomXml();
    		List<Person> list = domXml.getPersons(inputStream);
    		for(Person person : list) {
    			System.out.println(person.toString());
    		}
    	}
    }


    3)XMLPULL(org.xmlpull.v1) 方式

    1) 新建一个项目,导入kxml2-2.2.2.jar包,创建一个描述信息Person类。

            kxml2-2.2.2.jar包下载地址:http://download.csdn.net/detail/llping2010/6270791

    public class Person {
    
    	private String name;
    	private int age;
    	private int id;
    	
    	
    	public Person() {
    		// TODO Auto-generated constructor stub
    	}
    	
    	public Person(String name, int age, int id) {
    		super();
    		this.name = name;
    		this.age = age;
    		this.id = id;
    	}
    
    	/**
    	 * @return the name
    	 */
    	public String getName() {
    		return name;
    	}
    
    	/**
    	 * @param name the name to set
    	 */
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	/**
    	 * @return the age
    	 */
    	public int getAge() {
    		return age;
    	}
    
    	/**
    	 * @param age the age to set
    	 */
    	public void setAge(int age) {
    		this.age = age;
    	}
    
    	/**
    	 * @return the id
    	 */
    	public int getId() {
    		return id;
    	}
    
    	/**
    	 * @param id the id to set
    	 */
    	public void setId(int id) {
    		this.id = id;
    	}
    
    	/* (non-Javadoc)
    	 * @see java.lang.Object#toString()
    	 */
    	@Override
    	public String toString() {
    		return "Person [name=" + name + ", age=" + age + ", id=" + id + "]";
    	}
    }



    2) 创建一个PullXmlTools类,根据inputStream获取输入调用XmlPullParserFactoty解析XML将解析的数据保存到List<Person> list中返回。

    public class PullXmlTools {
    	
    	public PullXmlTools() {
    		// TODO Auto-generated constructor stub
    	}
    
    	public static List<Person> parseXml(InputStream inputStream, String encode) throws XmlPullParserException, IOException {
    		List<Person> list = null;
    		Person person = null;
    		
    		// 创建一个xml解析的工厂
    		XmlPullParserFactory xppFactovy = XmlPullParserFactory.newInstance(); 
    		// 获得xml解析类的引用
    		XmlPullParser parser = xppFactovy.newPullParser();
    		// 设置parser解析器的输入和编码类型
    		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())) {
    					person = new Person();
    					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.getEventType();
    		}	
    		return list;
    	}
    }
    



    3) 定义一个测试类Test,读取文件FileInputStream调用PullXmlTools.parserXml()处理。

    public class Test {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		
    		try {
    			File file = new File("C://test.xml");
    			if(file.exists()) {
    				FileInputStream inputStream = new FileInputStream(file);
    				List<Person> list = PullXmlTools.parseXml(inputStream, "utf-8");
    				for(Person person : list) {
    					System.out.println(person.toString());
    				}
    			} else {
    				System.out.println("file is not exitst");
    			}
    			
    		} catch (Exception e) {
    			// TODO: handle exception
    		}
    	}
    }


  • 相关阅读:
    js问题记录
    css问题记录
    vscode配置java+gradle开发环境
    js插件
    nginx笔记
    vue刷新当前路由
    koa踩坑记录
    react踩坑笔记
    ts踩坑笔记
    vue源码阅读笔记
  • 原文地址:https://www.cnblogs.com/riskyer/p/3323018.html
Copyright © 2020-2023  润新知