说明:此案例使用的是通过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,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 qName,Attributes attributes) throws SAXException { super.startElement(uri,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. 主要功能:
通过点击下拉列表里的城市进行切换,实现各城市风力的显示。