zoukankan      html  css  js  c++  java
  • 解析网络 xml 流程

    引用:http://www.cnblogs.com/boyupeng/archive/2011/04/06/2028529.html

    这几天看了mars老师的文章,其中有一个利用sax解析从网络中下载的xml文件,很受用。先来看看工程的架构:

    1

    其中FileUtils.java用来放一些常用的公共方法,这里放置对文件的读写

          HttpDownload.java用来从网上下载xml文件

          MyContentHandler.java为xml内容处理器类

          XMLActivity.java这个大家懂得,呵呵

    第一步,FileUtils.java,还是老样子,具体的解释放在代码注释中:

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import android.os.Environment;

    public class FileUtils
    {
    private String SDPATH;

    public String getSDPATH()
    {
    return SDPATH;
    }

    public FileUtils()
    {
    //得到当前外部存储设备的目录/SDCARD
    SDPATH = Environment.getExternalStorageDirectory() + "/";
    }

    /**
    * 在SD卡上创建文件
    *
    *
    @throws IOException
    */
    public File creatSDFile(String fileName) throws IOException
    {
    File file = new File(SDPATH + fileName);
    file.createNewFile();
    return file;
    }

    /**
    * 在SD卡上创建目录
    *
    *
    @param dirName
    */
    public File creatSDDir(String dirName)
    {
    File dir = new File(SDPATH + dirName);
    dir.mkdir();
    return dir;
    }

    /**
    * 判断SD卡上的文件夹是否存在
    */
    public boolean isFileExist(String fileName)
    {
    File file = new File(SDPATH + fileName);
    return file.exists();
    }

    /**
    * 将一个InputStream里面的数据写入到SD卡中
    */
    public File write2SDFromInput(String path, String fileName,
    InputStream input)
    {
    File file = null;
    OutputStream output = null;
    try
    {
    creatSDDir(path);
    file = creatSDFile(path + fileName);
    output = new FileOutputStream(file);
    byte buffer[] = new byte[4 * 1024];
    while ((input.read(buffer)) != -1)
    {
    output.write(buffer);
    }
    output.flush();
    }
    catch (Exception e)
    {
    e.printStackTrace();
    }
    finally
    {
    try
    {
    output.close();
    }
    catch (Exception e)
    {
    e.printStackTrace();
    }
    }
    return file;
    }

    }



    第二步,HttpDownload.java

    package my.utils;

    import java.io.BufferedReader;
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;

    public class HttpDownloader
    {
    private URL url = null;

    /**
    * 根据URL下载文件,前提是这个文件当中的内容是文本,函数的返回值就是文件当中的内容
    * 1.创建一个URL对象
    * 2.通过URL对象,创建一个HttpURLConnection对象
    * 3.得到InputStram
    * 4.从InputStream当中读取数据
    *
    @param urlStr
    *
    @return
    */
    public String download(String urlStr)
    {
    StringBuffer sb = new StringBuffer();
    String line = null;
    BufferedReader buffer = null;
    try
    {
    // 创建一个URL对象
    url = new URL(urlStr);
    // 创建一个Http连接
    HttpURLConnection urlConn = (HttpURLConnection) url
    .openConnection();
    // 使用IO流读取数据
    buffer = new BufferedReader(new InputStreamReader(urlConn
    .getInputStream()));
    while ((line = buffer.readLine()) != null)
    {
    sb.append(line);
    }
    }
    catch (Exception e)
    {
    e.printStackTrace();
    }
    finally
    {
    try
    {
    buffer.close();
    }
    catch (Exception e)
    {
    e.printStackTrace();
    }
    }
    return sb.toString();
    }

    /**
    * 该函数返回整形 -1:代表下载文件出错 0:代表下载文件成功 1:代表文件已经存在
    */
    public int downFile(String urlStr, String path, String fileName)
    {
    InputStream inputStream = null;
    try
    {
    FileUtils fileUtils = new FileUtils();

    if (fileUtils.isFileExist(path + fileName))
    {
    return 1;
    }
    else
    {
    inputStream = getInputStreamFromUrl(urlStr);
    File resultFile = fileUtils.write2SDFromInput(path, fileName,
    inputStream);
    if (resultFile == null)
    {
    return -1;
    }
    }
    }
    catch (Exception e)
    {
    e.printStackTrace();
    return -1;
    }
    finally
    {
    try
    {
    inputStream.close();
    }
    catch (Exception e)
    {
    e.printStackTrace();
    }
    }
    return 0;
    }

    /**
    * 根据URL得到输入流
    *
    *
    @param urlStr
    *
    @return
    *
    @throws MalformedURLException
    *
    @throws IOException
    */
    public InputStream getInputStreamFromUrl(String urlStr)
    throws MalformedURLException, IOException
    {
    url = new URL(urlStr);
    HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
    InputStream inputStream = urlConn.getInputStream();
    return inputStream;
    }
    }



    第三步,MyContentHandler.java

    package my.xml;

    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;

    import android.util.Log;

    public class MyContentHandler extends DefaultHandler
    {
    String hisname, address, money, sex, status;
    String tagName;

    /**
    * 开始解析xml
    *
    @throws SAXException
    */
    public void startDocument() throws SAXException
    {
    System.out.println("````````begin````````");
    }

    /**
    * 结束解析xml
    *
    @throws SAXException
    */
    public void endDocument() throws SAXException
    {
    System.out.println("````````end````````");
    }

    /**
    * 开始解析元素属性
    *
    *
    @param namespaceURI 命名空间,防止命名重复
    *
    @param localName 不带前缀的名字
    *
    @param qName 带前缀的名字
    *
    @param attr 代表标签里所有的属性
    *
    @throws SAXException
    */
    public void startElement(String namespaceURI, String localName,
    String qName, Attributes attr) throws SAXException
    {
    tagName = localName;//把当前正在解析的无前缀的名字传给tagName

    if (localName.equals("worker"))
    {
    //获取标签的全部属性
    for (int i = 0; i < attr.getLength(); i++)
    {
    Log.e("@@@", (attr.getLocalName(i) + "=" + attr.getValue(i)));//得到第i个属性的名字和值
    }
    }
    }

    /**
    * 结束元素解析
    *
    *
    @param namespaceURI
    *
    @param localName
    *
    @param qName
    *
    @throws SAXException
    */
    public void endElement(String namespaceURI, String localName, String qName)
    throws SAXException
    {
    //在workr标签解析完之后,会打印出所有得到的数据
    tagName = "";
    if (localName.equals("worker"))
    {
    this.printout();
    }
    }

    /**
    * 具体解析标签里的内容
    *
    *
    @param ch 所有读取到的内容,都会放到char[]类型的数组里
    *
    @param start 读取的内容是从char[]数组的哪一位开始
    *
    @param length 从start开始,一共有多长的内容
    *
    @throws SAXException
    */
    public void characters(char[] ch, int start, int length)
    throws SAXException
    {
    if (tagName.equals("name"))
    hisname = new String(ch, start, length);
    else if (tagName.equals("sex"))
    sex = new String(ch, start, length);
    else if (tagName.equals("status"))
    status = new String(ch, start, length);
    else if (tagName.equals("address"))
    address = new String(ch, start, length);
    else if (tagName.equals("money"))
    money = new String(ch, start, length);
    }

    private void printout()
    {
    System.out.print("name: ");
    System.out.println(hisname);
    System.out.print("sex: ");
    System.out.println(sex);
    System.out.print("status: ");
    System.out.println(status);
    System.out.print("address: ");
    System.out.println(address);
    System.out.print("money: ");
    System.out.println(money);
    System.out.println();
    }

    }



    第四步,在完成了上面三个类的编写,XMLActivity.java就只要实现简单的调用就可以了:

    package my.xml;

    import java.io.StringReader;

    import javax.xml.parsers.SAXParserFactory;

    import my.utils.HttpDownloader;
    import my.xml.R;

    import org.xml.sax.InputSource;
    import org.xml.sax.XMLReader;

    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;

    public class XMLActitity extends Activity
    {
    /** Called when the activity is first created. */
    private Button parseButton;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    parseButton = (Button) findViewById(R.id.parseButton);
    parseButton.setOnClickListener(new ParseButtonListener());
    }

    class ParseButtonListener implements OnClickListener
    {
    @Override
    public void onClick(View v)
    {
    HttpDownloader hd = new HttpDownloader();//new一个HttpDownloader对象
    String resultStr = hd
    .download("http://192.168.1.112/test.xml");//把下载的字符串放在resultStr
    try
    {
    /**
    * 创建一个SAXParserFactory,再用这个工厂来创建一个XMLReader,以此来读取XML
    * 这个方法就是这样写的,没有什么为什么,只是规定的格式罢了。
    */
    SAXParserFactory factory = SAXParserFactory.newInstance();
    XMLReader reader = factory.newSAXParser().getXMLReader();

    //为XMLReader设置内容处理器,MyContentHandler()为具体处理的类
    reader.setContentHandler(new MyContentHandler());
    //开始解析文件
    reader.parse(new InputSource(new StringReader(resultStr)));
    }
    catch (Exception e)
    {
    e.printStackTrace();
    }
    }

    }
    }



    在MyContentHandler 继承DefaultHandler中,主要是使用了适配器设计模式,不必实现接口中的所有方法。ok!

  • 相关阅读:
    使用 git 托管代码
    转载自网络大神
    i18n 国际化
    转自知乎大神---什么是 JS 原型链?
    转自知乎大神----JS 闭包是什么
    转自知乎大神----JS 的 new 到底是干什么的?
    转载自知乎大神---this 的值到底是什么?一次说清楚
    sql查看本机IP地址
    Python 编码规范(Google)
    Python在mysql中进行操作是十分容易和简洁的
  • 原文地址:https://www.cnblogs.com/sode/p/2290518.html
Copyright © 2011-2022 走看看