Android解析压缩的xml文件
2017-03-19 01:31
239 查看
Android解析压缩的xml文件
本文主要介绍xml文件解析,主要是想讲手机内压缩文件xml的解析,但是也顺便讲一下在目录assets中的xml文件的解析。这里压缩文件的解析,一般做法是把压缩文件解析到相同目录下,得到File对象后,对xml文件进行解析。
Xml文件解析是有三种方法的,这里使用的是sax解析,其他的还有pull解析和DOM解析,关于使用哪种解析方法好,在本文最后会说一下的。
要解析的文件cd.xml(压缩文件:cd.zip):
<?xml version="1.0" encoding="UTF-8"?> <CATALOG> <CD> <TITLE>Empire Burlesque</TITLE> <ARTIST>Bob Dylan</ARTIST> <COUNTRY>USA</COUNTRY> <COMPANY>Columbia</COMPANY> <PRICE>10.90</PRICE> <YEAR>1985</YEAR> </CD> <CD> <TITLE>Hide your heart</TITLE> <ARTIST>Bonnie Tyler</ARTIST> <COUNTRY>UK</COUNTRY> <COMPANY>CBS Records</COMPANY> <PRICE>9.90</PRICE> <YEAR>1988</YEAR> </CD> 。。。(后面还有几个CD!) </CATALOG>
数据解析后的界面设计效果:
点击删除可以删除相应的条目。但是只是视图上面的,文件内容没有做删除操作!
关键代码:
(一)从assets中得到文件的输入流
// 从assets里面获取文件, // 通过getAssets获取到的是读取流 InputStream is = context.getAssets().open(assetXmlName);
(二)解压文件的方法,直接拿来用就可以!
/* * 这个是解压ZIP格式文件的方法 * * @zipFileName:是传进来你要解压的文件路径,包括文件的名字; * * @outputDirectory:选择你要保存的路劲; * */ public void unzip(String zipFileName, String outputDirectory) throws Exception { ZipInputStream in = new ZipInputStream(new FileInputStream(zipFileName)); Log.e("TAG", "in==null"+(in==null)); ZipEntry z; String name = ""; String extractedFile = ""; int counter = 0; while ((z = in.getNextEntry()) != null) { name = z.getName(); Log.d("TAG", "unzipping file: " + name); if (z.isDirectory()) { Log.d("TAG", name + "is a folder"); // get the folder name of the widget name = name.substring(0, name.length() - 1); File folder = new File(outputDirectory + File.separator + name); folder.mkdirs(); if (counter == 0) { extractedFile = folder.toString(); } counter++; Log.d("TAG", "mkdir " + outputDirectory + File.separator + name); } else { Log.d("TAG", name + "is a normal file"); File file = new File(outputDirectory + File.separator + name); file.createNewFile(); // get the output stream of the file FileOutputStream out = new FileOutputStream(file); int ch; byte[] buffer = new byte[1024]; // read (ch) bytes into buffer while ((ch = in.read(buffer)) != -1) { // write (ch) byte from buffer at the position 0 out.write(buffer, 0, ch); out.flush(); } out.close(); } } in.close(); }
程序设计的全部代码:
(一)布局文件activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:gravity="center" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="CD资料" android:padding="10dp" android:textSize="40sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:background="#f00" > <TextView android:gravity="center" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="歌名" android:textSize="20sp" /> <TextView android:gravity="center" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="作者" android:textSize="20sp" /> <TextView android:gravity="center" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="国籍" android:textSize="20sp" /> <TextView android:gravity="center" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="公司" android:textSize="20sp" /> <TextView android:gravity="center" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="价格" android:textSize="20sp" /> <TextView android:gravity="center" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="出版年" android:textSize="20sp" /> <TextView android:gravity="center" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="编辑" android:textSize="20sp" /> </LinearLayout> <ListView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/listView" /> </LinearLayout>
(二)ListView中条目的布局文件item_data.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" > <TextView android:layout_width="0dp" android:layout_weight="1" android:layout_height="60dp" android:id="@+id/tv_title" android:textSize="10sp" android:gravity="center" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:layout_height="60dp" android:id="@+id/tv_artist" android:textSize="10sp" android:gravity="center" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:layout_height="60dp" android:id="@+id/tv_country" android:textSize="20sp" android:gravity="center" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:layout_height="60dp" android:id="@+id/tv_company" android:textSize="10sp" android:gravity="center" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:layout_height="60dp" android:id="@+id/tv_price" android:textSize="20sp" android:gravity="center" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:layout_height="60dp" android:id="@+id/tv_year" android:textSize="20sp" android:gravity="center" /> <Button android:layout_width="0dp" android:layout_weight="1" android:layout_height="60dp" android:id="@+id/btn_delete" android:textSize="20sp" android:gravity="center" android:text="删除" /> </LinearLayout>
(三)XmlBean文件
package com.example.seeview; /** * Bean文件,定义数据原型 */ public class XmlBean { //定义属性 private String title; private String artist; private String country; private String company; private float price; private int year; //定义get和set方法 public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getArtist() { return artist; } public void setArtist(String artist) { this.artist = artist; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public String getCompany() { return company; } public void setCompany(String company) { this.company = company; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } //定义toString方法 @Override public String toString() { return "XmlBean [title=" + title + ", artist=" + artist + ", country=" + country + ", company=" + company + ", price=" + price + ", year=" + year + "]"; } }
(四)解压工具类ZipToFileUtil
package com.example.seeview; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import android.util.Log; public class ZipToFileUtil { /* * 这个是解压ZIP格式文件的方法 * * @zipFileName:是传进来你要解压的文件路径,包括文件的名字; * * @outputDirectory:选择你要保存的路劲; * */ static void unzip(String zipFileName, String outputDirectory) throws Exception { ZipInputStream in = new ZipInputStream(new FileInputStream(zipFileName)); Log.e("TAG", "in==null"+(in==null)); ZipEntry z; String name = ""; String extractedFile = ""; int counter = 0; while ((z = in.getNextEntry()) != null) { name = z.getName(); Log.d("TAG", "unzipping file: " + name); if (z.isDirectory()) { Log.d("TAG", name + "is a folder"); // get the folder name of the widget name = name.substring(0, name.length() - 1); File folder = new File(outputDirectory + File.separator + name); folder.mkdirs(); if (counter == 0) { extractedFile = folder.toString(); } counter++; Log.d("TAG", "mkdir " + outputDirectory + File.separator + name); } else { Log.d("TAG", name + "is a normal file"); File file = new File(outputDirectory + File.separator + name); file.createNewFile(); // get the output stream of the file FileOutputStream out = new FileOutputStream(file); int ch; byte[] buffer = new byte[1024]; // read (ch) bytes into buffer while ((ch = in.read(buffer)) != -1) { // write (ch) byte from buffer at the position 0 out.write(buffer, 0, ch); out.flush(); } out.close(); } } in.close(); } }
(五)解析xml文件类
package com.example.seeview; import android.content.Context; import android.util.Log; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List; /** * 解析xml文件的类,这里使用sax解析数据 * */ public class ParseXml { Context context; //上下文 File xmlFileName; String assetXmlName;//assets文件的名字 // 要解析文件的输入流 InputStream is; // 创建一个List集合存放从XML文件获取到的数据 List<XmlBean> list = null; XmlBean xmlBean = null; //定义构造方法传人上下文 ParseXml(Context context,File xmlFileName){ this.context=context; this.xmlFileName=xmlFileName; } //定义构造方法传人上下文 ParseXml(Context context,String assetXmlName){ this.context=context; this.assetXmlName=assetXmlName; } // 使用SAX方法解析的结果 ,并返回集合对象 public List<XmlBean> saxXmlToList() { try { if (assetXmlName!=null) { // 从assets里面获取文件, // 通过getAssets获取到的是读取流 is = context.getAssets().open(assetXmlName); }else if (xmlFileName!=null) { //从文件对象 is=new FileInputStream(xmlFileName); } // 取得SAXParserFactory实例 SAXParserFactory factory = SAXParserFactory.newInstance(); // 从factory获取SAXParser实例 SAXParser parser = factory.newSAXParser(); // 实例化定义的Handler Myhandler handler = new Myhandler(); // 根据Handler规则解析输入流 parser.parse(is, handler); // 打印信息 handler.showMessage(); //返回集合对象 return list; } catch (Exception e) { e.printStackTrace(); } return null; } //实现SAX方法解析数据必须要借助DefaultHandler 类的实现 class Myhandler extends DefaultHandler { StringBuffer sb = null; // 根标签开始时 @Override public void startDocument() throws SAXException { super.startDocument(); list = new ArrayList<XmlBean>(); sb = new StringBuffer(); } // 节点开始时 @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); // 当遍历到Car节点就新建Car对象 if (localName.equals("CD")) { xmlBean = new XmlBean(); // car.id = attributes.getValue(0);// 获取第一个属性值,节点值在后面获取 } // 将字符长度设置为零,以便从新开始读取元素内就字符节点 sb.setLength(0); } // 读取字符流 @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); sb.append(ch, start, length); } // 节点结束时 @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); //判断节点并给对象赋值 if (localName.equals("TITLE")) { xmlBean.setTitle( sb.toString()); } else if (localName.equals("ARTIST")) { xmlBean.setArtist( sb.toString()); }else if (localName.equals("COUNTRY")) { xmlBean.setCountry( sb.toString()); }else if (localName.equals("COMPANY")) { xmlBean.setCompany( sb.toString()); }else if (localName.equals("PRICE")) { xmlBean.setPrice( Float.parseFloat(sb.toString())); }else if (localName.equals("YEAR")) { xmlBean.setYear( Integer.parseInt(sb.toString())); }else if (localName.equals("CD")) {//当一个回合结束再添加数据,很关键 list.add(xmlBean); } } public void showMessage() { // 打印获得的数据 for (XmlBean c : list) { Log.e("TAG", c.toString()); } } } //上面是SAX方法解析数据的过程 }
(六)ListView的适配器类
package com.example.seeview; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.TextView; import java.util.List; /** * ListView的适配器,传人集合数据 */ public class DataAdapter extends BaseAdapter{ // 创建一个List集合存放从XML文件获取到的数据 List<XmlBean> list = null; Context context; //构造器传人集合对象 DataAdapter(Context context,List<XmlBean> list){ this.list=list; this.context=context; } //返回集合的数据量 public int getCount() { return list.size(); } //每一条数据对于的对象 public XmlBean getItem(int position) { return list.get(position); } //条码的ID public long getItemId(int position) { return position; } //每个条目的试图对象 public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView==null){ convertView=View.inflate(context,R.layout.item_data,null); viewHolder=new ViewHolder(convertView); convertView.setTag(viewHolder); } else{ viewHolder= (ViewHolder) convertView.getTag(); } //给ListView的条码设置内容 viewHolder.tv_title.setText(list.get(position).getTitle()); viewHolder.tv_artist.setText(""+list.get(position).getArtist()); viewHolder.tv_country.setText(""+list.get(position).getCountry()); viewHolder.tv_company.setText(""+list.get(position).getCompany()); viewHolder.tv_price.setText(""+list.get(position).getPrice()); viewHolder.tv_year.setText(""+list.get(position).getYear()); //给按钮设置点击事件 viewHolder.btn_delete.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { //list.remove(position); //删除这个条目,在主方法操作 if(iDeleteData!=null){ iDeleteData.deleteData(position);//传递数据(点击的条目的序列号) } } }); return convertView; } //创建ViewHolder类 class ViewHolder{ TextView tv_title; TextView tv_artist; TextView tv_country; TextView tv_company; TextView tv_price; TextView tv_year; Button btn_delete; ViewHolder(View view){ tv_title= (TextView) view.findViewById(R.id.tv_title); tv_artist= (TextView) view.findViewById(R.id.tv_artist); tv_country= (TextView) view.findViewById(R.id.tv_country); tv_company= (TextView) view.findViewById(R.id.tv_company); tv_price= (TextView) view.findViewById(R.id.tv_price); tv_year= (TextView) view.findViewById(R.id.tv_year); btn_delete= (Button) view.findViewById(R.id.btn_delete); } } //设置一个回调接口 interface IDeleteData{ void deleteData(int position); } //定义接口对象 IDeleteData iDeleteData; //设置监听对象 public void setiDeleteData(IDeleteData iDeleteData) { this.iDeleteData = iDeleteData; } }
(七)主方法类
package com.example.seeview; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import android.app.Activity; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.ImageView; import android.widget.ListView; import android.widget.Toast; public class MainActivity extends Activity { // 创建一个List集合存放从XML文件获取到的数据 List<XmlBean> list = null; //布局的ListVIew ListView listView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView= (ListView) findViewById(R.id.listView); //创建解析对象 //解析Assets文件,输入文件名即可 ParseXml parseXml=new ParseXml(this,"cd.xml"); //解析本地的也是文件,要先解压文件 // String outputDirectory="mnt/sdcard/"; // String zipFileName="cd.zip"; // String outputFileName="cd.xml"; // try { // ZipToFileUtil.unzip(outputDirectory+zipFileName, outputDirectory); // ParseXml parseXml=new ParseXml(this,new File(outputDirectory+outputFileName)); // } catch (Exception e) { // Toast.makeText(this, "解压文件失败", Toast.LENGTH_LONG).show(); // finish(); // e.printStackTrace(); // } //解析数据,并返回结果 list= parseXml.saxXmlToList(); //创建Adapter,使用BaseAdapter final DataAdapter adapter=new DataAdapter(this,list); listView.setAdapter(adapter); //设置删除的监听 adapter.setiDeleteData(new DataAdapter.IDeleteData() { public void deleteData(int position) { list.remove(position);//删除条目数据 adapter.notifyDataSetChanged(); //刷新适配器 } }); } }
如果要解析手机中的压缩文件,要保证路径是正确的,并且要添加读写权限。上面解析压缩文件的代码已经注释调了,反注释后,并注释解析assets文件夹的文件的代码,运行,即可得到下面相同的效果。
手机运行后的效果;这里说一下,三种解析数据的应用场合:
Sax解析,适合读取整个文件的所有内容,并且是读取一次,速度较快。
Pull解析,适合读取文件中某些节点的数据,速度最快。
DOM解析,适合读取读取整个文件,并且可以反复获取,适合对一个文件的数据进行反复读取时使用,但是DOM耗时较多,它是把整个文档缓存下来!
本文中的xml文件,读取一次全部内容,并存储到集合中,是最有效的处理方法!也就是sax文件解析方式的使用。这里有我之前专门解析xml数据的三种方法的总结和它们的使用示例:
http://blog.csdn.net/wenzhi20102321/article/details/52774365
相关文章推荐
- Android中的AndroidManifest.xml文件解析
- AndroidManifest.xml文件解析
- android中解析XML文件方式—DOM SAX PULL
- android之sax解析xml文件 .
- Android配置文件Manifest.xml如何被加载、解析的
- Android中XML文件常用解析方式的比较分析
- Android使用Pull解析器解析XML文件
- android中访问和解析xml文件
- android 使用 pull 解析xml文件
- AndroidManifest.xml文件解析
- AndroidManifest.xml文件解析(2)
- AndroidManifest.xml 文件之详细解析
- android_xml解析之 使用PULL读取XML文件 .
- AndroidManifest.xml文件解析
- AndroidManifest.xml 文件之详细解析
- Android开发之XML文件解析
- Android之DOM解析XML文件
- android之sax解析xml文件
- android里pull解析xml文件
- AndroidManifest.xml文件解析