解析XML格式数据



滴水穿石不是靠力,而是因为不舍昼夜。



本讲内容:解析XML格式数据

解析XML格式的数据有多种方式,常用的两种是:Pull解析和SAX解析。


示例一:解析服务器返回的数据

下面是通过apache服务器生成get_data.xml文件。

一、Pull解析方式

步骤:

1、获取一个XmlPullParserFactory实例

XmlPullParserFactory factory = XmlPullParserFactory.newInstance();

2、通过factory这个实例得到XmlPullParser对象,然后调用XmlPullParser的setInput()方法将服务器返回的XML数据设置进去就可以开始解析了。

XmlPullParser xmlPullParser = factory.newPullParser();
xmlPullParser.setInput(new StringReader(xmlData));
3、解析过程:通过getEventType()方法得到当前的解析事件,然后在一个while循环中不断地进行解析,如果当前的解析事件不等于XmlPullParser.END_DOCUMENT,说明解析工作还没完成,调用next()方法后可以获取下一个解析事件。在while循环中,我们通过getName()方法得到当前结点的名字,调用nextText()方法来获取结点内具体的内容。


下面是MainActivity.java主界面文件:

public class MainActivity extends Activity implements OnClickListener {
	private Button sendRequest;

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		sendRequest = (Button) findViewById(R.id.id_send);
		sendRequest.setOnClickListener(this);
	}

	public void onClick(View v) {
		if (v.getId() == R.id.id_send) {
			sendRequestWithHttpClient();
		}
	}

	/**
	 * 使用HttpClient发送HTTP请求
	 */
	private void sendRequestWithHttpClient() {
		// 开启线程来发起网络请求
		new Thread(new Runnable() {
			public void run() {
				try {
					HttpClient httpClient = new DefaultHttpClient();// 创建一个DefaultHttpClient实例
					// 指定访问的服务器地址是电脑本机,10.0.2.2对于模拟器来说就是电脑本机的IP地址
					HttpGet httpGet = new HttpGet("http://10.0.2.2/get_data.xml");
					HttpResponse httpResponse = httpClient.execute(httpGet);
					if (httpResponse.getStatusLine().getStatusCode() == 200) {
						// 请求和响应都成功了
						HttpEntity entity = httpResponse.getEntity();// 获取一个HttpEntity实例,取出服务器返回的具体内容
						String response = EntityUtils.toString(entity, "utf-8");// 不写utf-8会出现乱码
						parseXMLWithPull(response);//通过Pull解析服务器返回的数据
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}).start();
		;
	}

	/**
	 * 通过Pull解析
	 */
	private void parseXMLWithPull(String xmlData) {
		try {
			XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
			XmlPullParser xmlPullParser = factory.newPullParser();
			xmlPullParser.setInput(new StringReader(xmlData));
			int eventType = xmlPullParser.getEventType();
			String id = "";
			String name = "";
			String version = "";
			while (eventType != XmlPullParser.END_DOCUMENT) {
				String nodeName = xmlPullParser.getName();
				switch (eventType) {
				// 开始解析某个结点
				case XmlPullParser.START_TAG: {
					if ("id".equals(nodeName)) {
						id = xmlPullParser.nextText();
					} else if ("name".equals(nodeName)) {
						name = xmlPullParser.nextText();
					} else if ("version".equals(nodeName)) {
						version = xmlPullParser.nextText();
					}
					break;
				}

				// 完成解析某个结点
				case XmlPullParser.END_TAG: {
					if ("app".equals(nodeName)) {
						Log.d("MainActivity", "id is " + id);
						Log.d("MainActivity", "name is " + name);
						Log.d("MainActivity", "version is " + version);
					}
					break;
				}
				}
				eventType = xmlPullParser.next();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

运行程序并点击按钮

     


二、SAX解析方式

步骤:

1、用法比Pull解析要复杂,但在语义方面会更加清楚。通常新建一个类继承自DefaultHandler,并重写父类的五个方法。

2、创建一个SAXParserFactory对象,然后再获取XMLReader对象,接着将我们编好的ContentHandler的实例设置到XMLReader中,最后调用parse()方法开始执行解析。

SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader xmlReader=factory.newSAXParser().getXMLReader();

下面是ContentHandler.java文件

public class ContentHandler extends DefaultHandler {
	private String nodeName;
	private StringBuilder id;
	private StringBuilder name;
	private StringBuilder version;
	
	/**
	 * 开始XML解析的时候调用
	 */
	public void startDocument() throws SAXException {
		id=new StringBuilder();
		name=new StringBuilder();
		version=new StringBuilder();
	}

	/**
	 * 开始解析某个结点的时候调用
	 */
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		//记录当前结点名
		nodeName=localName;
	}

	/**
	 * 获取结点中内容的时候调用。在获取结点中的内容时,characters()方法可能会被调用多次,
	 * 一些换行符也被当作内容解析出来,我们需要针对这种情况在代码中做好控制。
	 */
	public void characters(char[] ch, int start, int length)throws SAXException {
		//根据当前的结点名判断将内容添加到哪一个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);
		}
	}

	/**
	 * 完成解析某个结点的时候调用
	 */
	public void endElement(String uri, String localName, String qName)throws SAXException {
		if("app".equals(localName)){
			Log.d("MainActivity", "id is "+id.toString().trim());
			Log.d("MainActivity", "name is "+name.toString().trim());
			Log.d("MainActivity", "version is "+version.toString().trim());
			//最后要将StringBuilder清空掉
			id.setLength(0);
			name.setLength(0);
			version.setLength(0);
		}
	}
	
	/**
	 * 完成整个XML解析的时候调用
	 */
	public void endDocument() throws SAXException {
		
	}
}


下面是MainActivity.java文件

public class MainActivity extends Activity implements OnClickListener {
	private Button sendRequest;

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		sendRequest = (Button) findViewById(R.id.id_send);
		sendRequest.setOnClickListener(this);
	}

	public void onClick(View v) {
		if (v.getId() == R.id.id_send) {
			sendRequestWithHttpClient();
		}
	}

	/**
	 * 使用HttpClient发送HTTP请求
	 */
	private void sendRequestWithHttpClient() {
		// 开启线程来发起网络请求
		new Thread(new Runnable() {
			public void run() {
				try {
					HttpClient httpClient = new DefaultHttpClient();// 创建一个DefaultHttpClient实例
					// 指定访问的服务器地址是电脑本机,10.0.2.2对于模拟器来说就是电脑本机的IP地址
					HttpGet httpGet = new HttpGet("http://10.0.2.2/get_data.xml");
					HttpResponse httpResponse = httpClient.execute(httpGet);
					if (httpResponse.getStatusLine().getStatusCode() == 200) {
						// 请求和响应都成功了
						HttpEntity entity = httpResponse.getEntity();// 获取一个HttpEntity实例,取出服务器返回的具体内容
						String response = EntityUtils.toString(entity, "utf-8");// 不写utf-8会出现乱码
						parseXMLWithSAX(response);//通过Pull解析服务器返回的数据
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}).start();
		;
	}

	/**
	 * 通过SAX解析
	 */
	private void parseXMLWithSAX(String xmlData) {
		try {
			SAXParserFactory factory = SAXParserFactory.newInstance();
			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();
		}
	}
}

运行程序并点击按钮




Take your time and enjoy it 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值