Xml的三种常用解析方法

一般在开发中,请求到的数据有事会是Json串,但是有时候也会是XML文件类型的数据文本,那么我们怎么对XML类型的数据进行解析呢?

一般我们有三种比较常用的解析方式,DOM解析,SAX解析,和PULL解析。

下面先说一下DOM解析:DOM解析是文档驱动类型,即将整个文档全部读取,然后进行解析,速度相对较慢。

先看要解析的XML文件:


   
   

   
   
    
    
     
     
      
      李明
     
     
     
     
      
      30
     
     
    
    
    
    
     
     
      
      李向梅
     
     
     
     
      
      25
     
     
    
    
   
   
下面是解析代码:

public class MainActivity extends Activity {
	private ListView listView;
	private ArrayList
   
   
    
     list;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		list = new ArrayList
    
    
     
     ();
		listView = (ListView) findViewById(R.id.listView);

	}

	public void parse(View v) {
		// 实例化 DOM解析工厂类:DocumentBuilderFactory。得到解析工厂类对象
		DocumentBuilderFactory instance = DocumentBuilderFactory.newInstance();
		// 获得解析者对象:DocumentBuilder
		try {
			DocumentBuilder builder = instance.newDocumentBuilder();
			// 解析XML文件,得到文档对象
			Document document = builder.parse(getAssets().open("source.xml"));
			// 找节点----获取文档元素对象
			Element element = document.getDocumentElement();
			// 获取person节点,getelementsByTagName:通过标签名字获取节点
			NodeList nodeList = element.getElementsByTagName("person");
			// 遍历
			for (int i = 0; i < nodeList.getLength(); i++) {
				Person person = new Person();
				// 取出属性node,然后强转成Element元素:等于取出每个元素
				Element item = (Element) nodeList.item(i);
				String id = item.getAttribute("id");
				person.setId(id);
				// 取出子节点
				NodeList childNodes = item.getChildNodes();
				// 遍历
				for (int j = 0; j < nodeList.getLength(); j++) {
					// 取出每个子节点
					Node node = childNodes.item(j);
					// 得到节点类型
					short nodeType = node.getNodeType();
					// 判断是否是元素类型
					if (nodeType == node.ELEMENT_NODE) {
						// 判断是哪个节点
						if (node.getNodeName().equals("name")) {
							// 取出文本
							String name = node.getFirstChild().getTextContent();
							person.setName(name);
						} else if (node.getNodeName().equals("age")) {
							String age = node.getFirstChild().getTextContent();
							person.setAge(age);
						}

					}
				}
				list.add(person);

			}

			listView.setAdapter(new ArrayAdapter
     
     
      
      (MainActivity.this,
					android.R.layout.simple_list_item_1, list));

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
     
     
    
    
   
   

第二种是SAX解析:SAX解析是以事件驱动类型的解析方式,速度相对较快

代码如下(分为了两个类,一个是Activity,另一个是类似于帮助类的方法类):

public class MainActivity extends Activity {
	private ListView listView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		listView = (ListView) findViewById(R.id.listView);

	}

	public void jiexi(View v) {
		// 得到sax解析工厂类
		SAXParserFactory factory = SAXParserFactory.newInstance();
		try {
			// 得到具体的解析者
			SAXParser parser = factory.newSAXParser();
			MyHelper myHelper = new MyHelper();
			// 解析
			parser.parse(getAssets().open("source.xml"), myHelper);
			// 调用MyHelper的方法,得到集合
			ArrayList
   
   
    
     list = myHelper.getList();
			// 设置listView适配器
			listView.setAdapter(new ArrayAdapter
    
    
     
     (MainActivity.this,
					android.R.layout.simple_list_item_1, list));

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
    
    
   
   


具体的解析任务是放在帮助类里的

public class MyHelper extends DefaultHandler {

	private ArrayList
   
   
    
     list;
	private String tag;
	private Person person;
	
	
	//返回集合数据的方法
	public ArrayList
    
    
     
      getList(){
		return list;
	}

	// 开始解析文档时调用
	@Override
	public void startDocument() throws SAXException {

		super.startDocument();
		list = new ArrayList
     
     
      
      ();

	}

	// 结束文档解析时调用
	@Override
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.endDocument();
	}

	// 开始解析节点时调用
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		super.startElement(uri, localName, qName, attributes);

		tag = localName;
		if (localName.equals("person")) {
			person = new Person();
			String id = attributes.getValue("id");
			person.setId(id);
		}
	}

	// 结束解析节点时调用
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		super.endElement(uri, localName, qName);
		if (localName.equals("person")) {
			list.add(person);
		}
	}

	// 拼接字符串
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		super.characters(ch, start, length);
		String str = new String(ch, start, length);
		if (tag.equals("name")) {
			person.setName(str);
		} else if (tag.equals("age")) {
			person.setAge(str);
		}

	}

}
     
     
    
    
   
   


第三种解析方式PULL解析:

也是以事件驱动为类型的解析方式。

代码如下:

public class MainActivity extends Activity {
	private ArrayList
   
   
    
     list = null;
	private Person person = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		Button parse = (Button) findViewById(R.id.parse);
		parse.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				/**
				 * 1.factory 2.解析者 3.解析
				 */
				XmlPullParser pullParser = Xml.newPullParser();// 获取解析者
				try {
					// pullParser.setInput(inputStream--输入流, inputEncoding--输入流的编码);
					pullParser.setInput(getAssets().open("source.xml"), "UTF-8");
					// 实例化集合
					list = new ArrayList
    
    
     
     ();
					// 获取事件类型
					int eventType = pullParser.getEventType();
					// 判断事件类型
					// 如果文档没有结束,就要一直解析
					while (eventType != XmlPullParser.END_DOCUMENT) {
						//
						switch (eventType) {
						// 判断节点名字
						case XmlPullParser.START_TAG:
							// 获取节点名字
							String startTagName = pullParser.getName();
							if (startTagName.equals("person")) {
								// 实例化person对象
								person = new Person();
								// 设置属性
								person.setId(pullParser.getAttributeValue(null,"id"));
							} else if (startTagName.equals("name")) {
								person.setName(pullParser.nextText());
							} else if (startTagName.equals("age")) {
								person.setAge(pullParser.nextText());
							}
							break;
						case XmlPullParser.END_TAG:
							// 获取节点名字
							String endTagName = pullParser.getName();
							if (endTagName.equals("person")) {
								list.add(person);
							}
							break;
						default:
							break;
						}
						// 事件往下移动
						eventType = pullParser.next();
					}
					// 展示
					for (int i = 0; i < list.size(); i++) {
						System.out.println("zhanghi----->"
								+ list.get(i).getName());
					}
				} catch (XmlPullParserException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
	}
}
    
    
   
   

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值