1、首先,在布局文件中写一个Button控件和用来展示数据的ListView控件。
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="获取xml" android:onClick="getdata"/> <ListView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/lv_main_data"> </ListView>2、新建一个布局文件,用于listview展示数据,在这个布局文件中增加你要显示数据的TextView控件。代码如下:<TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:textAppearance="?android:attr/textAppearanceLarge" android:text="dfd" android:id="@+id/tv_listview_one" /> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:textAppearance="?android:attr/textAppearanceLarge" android:text="dfd" android:id="@+id/tv_listview_two" /> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:textAppearance="?android:attr/textAppearanceLarge" android:text="dfd" android:id="@+id/tv_listview_three" />然后在MainActivity.java通过解析XML拿到数据。解析XML有三种方法,方法如下:
一、DOM解析器
DOM(Document Object Model):是一种用于XML文档的对象模型,直接访问XML文档中所有部分。
特点:解析速度快,一次性解析整个文档。加载大文件时候效率低。代码如下:
public class MainActivity extends AppCompatActivity { PRivate ListView lv_main_data; private ProgressDialog pd; private List<UserEntity> lists = new ArrayList<>(); private MainActivity.myadapter myadapter; String currentTag=null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv_main_data = (ListView) findViewById(R.id.lv_main_data);//拿到listview的ID myadapter = new myadapter(); lv_main_data.setAdapter(myadapter); pd = new ProgressDialog(this);//动画加载中 pd.setMessage("locaging....."); } class myadapter extends BaseAdapter{ @Override public int getCount() { return lists.size(); } @Override public Object getItem(int position) { return lists.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView==null){ convertView= LayoutInflater.from(MainActivity.this).inflate(R.layout.dom_listview,null); DomActivity activity=new DomActivity(); activity.uname= (TextView) convertView.findViewById(R.id.tv_listview_one); activity.content= (TextView) convertView.findViewById(R.id.tv_listview_two); activity.anthour= (TextView) convertView.findViewById(R.id.tv_listview_three); convertView.setTag(activity); } DomActivity domActivity= (DomActivity) convertView.getTag(); domActivity.uname.setText(lists.get(position).getUname()); domActivity.content.setText(lists.get(position).getContent()); domActivity.anthour.setText(lists.get(position).getAnthour()); return convertView; } }//获取xml数据 public void getdata(View view){ new mytask().execute(); pd.show(); } //写一个继承AsyncTask,重写它的两个方法 // 1、获取网络数据:doInBackground // 2、更新UI(数据):onPostExecute class mytask extends AsyncTask{ private UserEntity userEntity; private UserEntity userEntity1; @Override protected Object doInBackground(Object[] params) { final List<UserEntity> list = new ArrayList<>(); //获取网络数据:定义获取网络数据的路径 String path="http://192.168.43.143:8080/android/android_xml.xhtml"; try { URL url=new URL(path);//实例化url:将获取网络数据的路径放到URL中。 HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();//获取连接的对象 httpURLConnection.setRequestMethod("GET");//设置请求的方式:1、get;2、post httpURLConnection.setConnectTimeout(5000);//请求连接超时的时间 int code=httpURLConnection.getResponseCode(); //获取响应码的值 if (code==200){//判断:如果响应码等于200时,获取返回过来的是XML数据 //通过流的形式读取 InputStream inputStream=httpURLConnection.getInputStream(); //测试:是否拿到值 String str=null; //字符流// BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));//把字符流转成字节流// while ((str=bufferedReader.readLine())!=null){// Log.i("test", "doInBackground: ");} // 解析XML: 1、DOM 2、SAX 3、PULL // 一、使用DOM解析 try { // 1、使用DOM解析:特点:一次性解析整个文档 // (工厂模式就是单列模式 只要有newInstance就是单列模式) DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();//创建工厂构建器,再拿DOM解析器 DocumentBuilder builder=factory.newDocumentBuilder();//创建document的构建器,通过工厂拿到DOM解析器 Document document=builder.parse(inputStream);//解析数流:通过解析器拿到数流 //DOM解析的原理:1、获取文档的标签(跟标签) Element root=document.getDocumentElement(); Log.i("test", "doInBackground: "+root.getTagName()); //2、获取文档的标签下所有的子节点 NodeList node=root.getElementsByTagName("fq");//获取节点 for (int i = 0; i <node.getLength() ; i++) { Element element= (Element) node.item(i); //3、获取节点下的属性 String name=element.getAttribute("name"); Log.i("test", "doInBackground: "+name); //4、获取子标签(拿标签的值) Element element1= (Element) element.getElementsByTagName("content").item(0); String content=element1.getTextContent(); Element element2= (Element) element.getElementsByTagName("anthour").item(0); String anthour=element2.getTextContent(); Log.i("test", "doInBackground: "+content+" ; "+anthour); UserEntity ue=new UserEntity(name,content,anthour); list.add(ue); } } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return list; } @Override//更新UI(数据) protected void onPostExecute(Object o) { super.onPostExecute(o); List<UserEntity> list= (List<UserEntity>) o; lists.addAll(list); myadapter.notifyDataSetChanged(); pd.cancel(); } }}二、SAX解析器
SAX(Simple API XML):使用流的形式处理,是一种以基于事件(方法)为驱动的解析器。
特点:边读边解析,解析速度快,占用内存少,同时sax解析提供了很多方法:开始、结束标签;开始、结束文档;文本的方法。代码如下:
public class MainActivity extends AppCompatActivity { private ListView lv_main_data; private ProgressDialog pd; private List<UserEntity> lists = new ArrayList<>(); private MainActivity.myadapter myadapter; String currentTag=null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv_main_data = (ListView) findViewById(R.id.lv_main_data);//拿到listview的ID myadapter = new myadapter(); lv_main_data.setAdapter(myadapter); pd = new ProgressDialog(this);//动画加载中 pd.setMessage("locaging....."); } class myadapter extends BaseAdapter{ @Override public int getCount() { return lists.size(); } @Override public Object getItem(int position) { return lists.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView==null){ convertView= LayoutInflater.from(MainActivity.this).inflate(R.layout.dom_listview,null); DomActivity activity=new DomActivity(); activity.uname= (TextView) convertView.findViewById(R.id.tv_listview_one); activity.content= (TextView) convertView.findViewById(R.id.tv_listview_two); activity.anthour= (TextView) convertView.findViewById(R.id.tv_listview_three); convertView.setTag(activity); } DomActivity domActivity= (DomActivity) convertView.getTag(); domActivity.uname.setText(lists.get(position).getUname()); domActivity.content.setText(lists.get(position).getContent()); domActivity.anthour.setText(lists.get(position).getAnthour()); return convertView; } }//获取xml数据 public void getdata(View view){ new mytask().execute(); pd.show(); } //写一个继承AsyncTask,重写它的两个方法 // 1、获取网络数据:doInBackground // 2、更新UI(数据):onPostExecute class mytask extends AsyncTask{ private UserEntity userEntity; private UserEntity userEntity1; @Override protected Object doInBackground(Object[] params) { final List<UserEntity> list = new ArrayList<>(); //获取网络数据:定义获取网络数据的路径 String path="http://192.168.43.143:8080/android/android_xml.xhtml"; try { URL url=new URL(path);//实例化url:将获取网络数据的路径放到URL中。 HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();//获取连接的对象 httpURLConnection.setRequestMethod("GET");//设置请求的方式:1、get;2、post httpURLConnection.setConnectTimeout(5000);//请求连接超时的时间 int code=httpURLConnection.getResponseCode(); //获取响应码的值 if (code==200){//判断:如果响应码等于200时,获取返回过来的是XML数据 //通过流的形式读取 InputStream inputStream=httpURLConnection.getInputStream(); //测试:是否拿到值 String str=null; // 解析XML: 1、DOM 2、SAX 3、PULL // 二;使用sax解析 try { //1、使用SAX解析:特点:边读边解析,基于事件(方法)驱动 // sax解析提供了很多的方法:开始标签 开始文档的方法,结束标签 结束文档的方法 文本 //创建sax工厂模式,通过工厂拿到解析器(和DOM解析一样) SAXParserFactory parserFactory=SAXParserFactory.newInstance();//创建sax工厂 SAXParser saxParser=parserFactory.newSAXParser();//拿到解析器 saxParser.parse(inputStream,new DefaultHandler(){//实现sax解析的方法 //开始文档的方法 @Override public void startDocument() throws SAXException { super.startDocument(); } //结束文档的方法 @Override public void endDocument() throws SAXException { super.endDocument(); } //开始标签的方法 @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { //1、拿到开始标签的名字:在DOM解析中,使用element拿到开始标签的名字。在sax解析中开始标签方法已经拿到了开始标签的名字 super.startElement(uri, localName, qName, attributes); //2、拿到名字进行判断 currentTag=localName; if ("fq".equals(localName)){//如果拿到的开始标签的名字是fq //实列化对象 userEntity = new UserEntity(); //通过attributes拿属性的值.attributes多个属性的值 String name=attributes.getValue(0); userEntity.setUname(name);//通过对象拿到标签属性的名字 } } //结束标签的方法 @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); currentTag=null; if ("fq".equals( localName)){ list.add(userEntity); } } //字符的方法 @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); if ("content".equals(currentTag)){ String content=new String(ch, start, length); userEntity.setContent(content); }else if ("anthour".equals(currentTag)){ String anthour=new String(ch, start, length); userEntity.setAnthour(anthour); } } }); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return list; } @Override//更新UI(数据) protected void onPostExecute(Object o) { super.onPostExecute(o); List<UserEntity> list= (List<UserEntity>) o; lists.addAll(list); myadapter.notifyDataSetChanged(); pd.cancel(); } }}三、PULL解析器
Pull解析器与SAX解析器性质类似,都是基于事件处理模式。不同的是用法:Pull解析器需要自己获取事件后做出相当于的操作,pull是用于Android,用于Java中需要导入pull解析依赖包。
特点:解析速度快、使用方便、效率高。代码如下:
public class MainActivity extends AppCompatActivity { private ListView lv_main_data; private ProgressDialog pd; private List<UserEntity> lists = new ArrayList<>(); private MainActivity.myadapter myadapter; String currentTag=null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv_main_data = (ListView) findViewById(R.id.lv_main_data);//拿到listview的ID myadapter = new myadapter();//实列化方法 lv_main_data.setAdapter(myadapter);//给listview一个适配器 pd = new ProgressDialog(this);//动画加载中 pd.setMessage("locaging....."); } class myadapter extends BaseAdapter{//写一个类继承baseadapter,重写它的方法 @Override public int getCount() {//获取集合数量 return lists.size(); } @Override public Object getItem(int position) {//获取当前集合 return lists.get(position); } @Override public long getItemId(int position) {//获取当前位置 return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView==null){ convertView= LayoutInflater.from(MainActivity.this).inflate(R.layout.dom_listview,null); DomActivity activity=new DomActivity();//实列化对象 activity.uname= (TextView) convertView.findViewById(R.id.tv_listview_one);//将每个属性增加到每个控件ID中 activity.content= (TextView) convertView.findViewById(R.id.tv_listview_two); activity.anthour= (TextView) convertView.findViewById(R.id.tv_listview_three); convertView.setTag(activity);//获取标签的属性 } DomActivity domActivity= (DomActivity) convertView.getTag();//得到标签 domActivity.uname.setText(lists.get(position).getUname());//通过标签得到值 domActivity.content.setText(lists.get(position).getContent()); domActivity.anthour.setText(lists.get(position).getAnthour()); return convertView; } }//获取xml数据 public void getdata(View view){ new mytask().execute(); pd.show();//画面展示 } //写一个继承AsyncTask,重写它的两个方法 // 1、获取网络数据:doInBackground // 2、更新UI(数据):onPostExecute class mytask extends AsyncTask{ private UserEntity userEntity; private UserEntity userEntity1; @Override protected Object doInBackground(Object[] params) { final List<UserEntity> list = new ArrayList<>(); //获取网络数据:定义获取网络数据的路径 String path="http://192.168.43.143:8080/android/android_xml.xhtml"; try { URL url=new URL(path);//实例化url:将获取网络数据的路径放到URL中。 HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();//获取连接的对象 httpURLConnection.setRequestMethod("GET");//设置请求的方式:1、get;2、post httpURLConnection.setConnectTimeout(5000);//请求连接超时的时间 int code=httpURLConnection.getResponseCode(); //获取响应码的值 if (code==200){//判断:如果响应码等于200时,获取返回过来的是XML数据 //通过流的形式读取 InputStream inputStream=httpURLConnection.getInputStream(); //测试:是否拿到值 String str=null; //字符流// BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));//把字符流转成字节流// while ((str=bufferedReader.readLine())!=null){// Log.i("test", "doInBackground: ");} // 解析XML: 1、DOM 2、SAX 3、PULL // 三、使用pull解析 try { //01、pull解析:需要jar包,写一个类即可(XMLpullparser)--XMLpull解析器 XmlPullParser pullParser= Xml.newPullParser(); pullParser.setInput(inputStream,"utf-8");//获得数流形式以及编码格式 //02、通过解析器拿到事件类型:开始标签,结束标签,开始文档,结束文档,文本 int type=pullParser.getEventType();//type-- 开始文档 //03、拿到开始文档进行判断 while (type!=XmlPullParser.END_DOCUMENT){//如果开始文档不等于结束标签,type必须赋值,否则会出现死循环 //type不断的改变,需要通过switch来判断 switch (type){ case XmlPullParser.START_TAG://如果是开始标签 //获取开始标签的名字 String startname= pullParser.getName(); if ("fq".equals(startname)){ //实列化对象 userEntity1 = new UserEntity(); String name=pullParser.getAttributeValue(0);//通过解析器得到值 userEntity1.setUname(name); }else if ("content".equals(startname)){ String content= pullParser.nextText();//通过解析器拿到下一个文本内容 userEntity1.setContent(content); }else if ("anthour".equals(startname)){ String anthour= pullParser.nextText();//通过解析器拿到下一个文本内容 userEntity1.setAnthour(anthour); } break; case XmlPullParser.END_TAG://如果是结束标签 //获取结束标签 String sname= pullParser.getName();//通过pull解析器获取结束标签的名字 if ("fq".equals(sname)){ list.add(userEntity1); } break; } type=pullParser.next();//通过解析器拿到下一个的值 } } catch (XmlPullParserException e) { e.printStackTrace(); } } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return list; } @Override//更新UI(数据) protected void onPostExecute(Object o) { super.onPostExecute(o); List<UserEntity> list= (List<UserEntity>) o; lists.addAll(list); myadapter.notifyDataSetChanged(); pd.cancel(); } }}5、需要增加网络权限。<uses-permission android:name="android.permission.INTERNET"></uses-permission>
新闻热点
疑难解答