通过Sax方式解析xml文件

说明:此案例使用的是通过Dom方式解析xml文件这篇文章里的City类和china.xml文件。

1. 因为xml文件有两种格式,一是上面那篇文章里的那种元素节点里只包含属性节点,另一种就是元素节点里包含元素节点和文本节点,于是在china.xml中添加如下代码,以实现两种方式的解析:

<city>
        <cityname>杭州</cityname>
        <pyName>zhejiang</pyName>
        <quName>浙江</quName>
        <state1>1</state1>
        <state2>1</state2>
        <stateDetailed>阴</stateDetailed>
        <tem1>34</tem1>
        <tem2>20</tem2>
        <windState>东北风1-2级</windState>
    </city>

2. 布局文件有变,用Spinner控件代替了RadioGroup控件,界面如下图:


3. 因为使用了Spinner控件,所以要在res/values文件夹下创建一个array.xml文件,用来获取Spinner控件中的item值,如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    
    <string-array name="cities">
        <item>北京</item>
        <item>江苏</item>
        <item>浙江</item>
    </string-array>
    
</resources>

string.xml文件中的Spinner控件:

<Spinner
        android:id="@+id/sp_cities"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:entries="@array/cities"
        android:layout_below="@+id/textView1" />

4. SAXXML类中的主要代码如下,有详解注释:
public class SAXXML {
	public List<City> saxXml() {
		MyDefaultHandler myHandler = new MyDefaultHandler();
		// 1.创建解析器工厂对象
		SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
		// 2.使用当前配置的工厂参数创建SAXParser的一个新实例(解析器对象)
		try {
			SAXParser saxParser = saxParserFactory.newSAXParser();
			// 3.解析xml文件
			saxParser.parse(
					getClass().getClassLoader()
							.getResourceAsStream("china.xml"),
					myHandler);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return myHandler.getCities();
	}

	// 事件驱动的处理者
	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 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("cityname")) {
					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);
				}
			}
		}

		@Override
		public void endDocument() throws SAXException {
			super.endDocument();
			System.out.println("---endDocument()---");
		}

		@Override
		public void endElement(String uri, String localName, String qName)
				throws SAXException {
			super.endElement(uri, localName, qName);
			if (qName.equals("city")) {
				cities.add(currentCity);
				currentCity = null;
			}
			this.tagName = null;
		}

		// 开始解析文档
		@Override
		public void startDocument() throws SAXException {
			super.startDocument();
			System.out.println("---startDocument()---");
			cities = new ArrayList<>();
		}

		@Override
		public void startElement(String uri, String localName, String qName,
				Attributes attributes) throws SAXException {
			super.startElement(uri, localName, qName, attributes);
			//判断标签是不是city标签
			if (qName.equals("city")) {
				//实例化对象
				currentCity = new City();
				//判断属性对象是否为空
				if (attributes != 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"));
				}
			}
			this.tagName = qName;
		}
	}
}
5.  MainActivity的主要步骤是:获取控件对象,实现OnItemSelectedListener接口注册监听事件,获取字符串数组,设置控件的默认值,获取解析的xml文件等,主要代码如下:
public class MainActivity extends Activity implements OnItemSelectedListener {

	private Spinner sp_cities;
	private TextView tv_fengli;

	private String cities[];

	private SAXXML saxXml;

	private List<City> entities;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		// 获取控件对象
		sp_cities = (Spinner) findViewById(R.id.sp_cities);
		tv_fengli = (TextView) findViewById(R.id.tv_fengli);
		// 注册事件
		sp_cities.setOnItemSelectedListener(this);
		// 获取字符串数组
		cities = getResources().getStringArray(R.array.cities);

		saxXml = new SAXXML();
		// 设置控件的默认值
		sp_cities.setSelection(2);
		// 获取解析的xml文件
		entities = saxXml.saxXml();
	}

	@Override
	public void onItemSelected(AdapterView<?> parent, View view, int position,
			long id) {
		for (City c : entities) {
			// 找到对应的city对象
			if (c.getQuName().equals(cities[position])) {
				// 设置风力
				tv_fengli.setText(c.getWindState());
				break;
			}
		}
	}

	@Override
	public void onNothingSelected(AdapterView<?> parent) {
		System.out.println("nothing");
	}

}
6. 主要功能:
通过点击下拉列表里的城市进行切换,实现各城市风力的显示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值