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控件。代码如下:
"0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="dfd"
android:id="@+id/tv_listview_one"
/>
"0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="dfd"
android:id="@+id/tv_listview_two"
/>
"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(Document Object Model):是一种用于XML文档的对象模型,直接访问XML文档中所有部分。
特点:解析速度快,一次性解析整个文档。加载大文件时候效率低。代码如下:
public class MainActivity extends AppCompatActivity {
private ListView lv_main_data;
private ProgressDialog pd;
private List 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 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 //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 list= (List) o;
lists.addAll(list);
myadapter.notifyDataSetChanged();
pd.cancel();
}
}
}
SAX(Simple API XML):使用流的形式处理,是一种以基于事件(方法)为驱动的解析器。
特点:边读边解析,解析速度快,占用内存少,同时sax解析提供了很多方法:开始、结束标签;开始、结束文档;文本的方法。代码如下:
public class MainActivity extends AppCompatActivity {
private ListView lv_main_data;
private ProgressDialog pd;
private List 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 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 list= (List) o;
lists.addAll(list);
myadapter.notifyDataSetChanged();
pd.cancel();
}
}}
Pull解析器与SAX解析器性质类似,都是基于事件处理模式。不同的是用法:Pull解析器需要自己获取事件后做出相当于的操作,pull是用于Android,用于Java中需要导入pull解析依赖包。
特点:解析速度快、使用方便、效率高。代码如下:
public class MainActivity extends AppCompatActivity {
private ListView lv_main_data;
private ProgressDialog pd;
private List 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 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 list= (List) o;
lists.addAll(list);
myadapter.notifyDataSetChanged();
pd.cancel();
}
}
}
5、需要增加网络权限。
<uses-permission android:name="android.permission.INTERNET">uses-permission>