zoukankan      html  css  js  c++  java
  • 数据存储(两)--SAX发动机XML记忆(附Demo)

    Android SDK支撑SAX读取技术XML,SAX通过连续的读取方式来处理XML文件。这要求每个读数XML对应的事件触发,以处理该节点的文件的节点。以下是基于一个例子来告诉SAX使用:

    public class Book 
    {
    	private String name;
    	private String id;
    	private String price;
    	private String publisher;
    	private int count;
        .... get,set方法省略
    }

    XML文件例如以下:

    <?xml version="1.0" encoding="utf-8"?>
    <books  xmlns:book="http://schemas.android.com/com.example.jsonxmlio">   
        <book 
            book:name="语文"
            book:id="001" 
           	book:price="45"
           	book:publisher="A">12</book>
        <book 
            book:name="数学"
            book:id="002" 
           	book:price="50"
           	book:publisher="B">10</book>
        <book 
            book:name="英语"
            book:id="003" 
           	book:price="55"
           	book:publisher="C">21</book> 
    </books>


    XMLTool.java

    1.构建一个工厂SAXParserFactory
    2.构建并实例化SAXPraser对象

    public class XMLTool {
    	
    	private static SAXParser getSAXParser() throws ParserConfigurationException, SAXException
    	{
            SAXParserFactory parserFactory = SAXParserFactory.newInstance();
            return parserFactory.newSAXParser();
    	}
    	public static DefaultHandler parse(InputStream inStream,DefaultHandler handler){
    		if(inStream!=null){
    			try {
    				SAXParser parser = getSAXParser();
    				parser.parse(inStream, handler);
    				return handler;
    			} catch (Exception e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}finally{
    				if(inStream!=null){
    					try {
    						inStream.close();
    					} catch (IOException e) {
    						// TODO Auto-generated catch block
    						e.printStackTrace();
    					}
    				}
    			}
    		}
    		return null;
    	}
    }

    BookXMLParser.java

    public class BookXMLParser extends DefaultHandler
    {
    	
    	private ArrayList<Book> dataList;
    	private Book book;
    	private StringBuffer stringBuffer = new StringBuffer();
    	//private StringBuffer buffer=new StringBuffer();
    	
    	public ArrayList<Book> getData()
    	{
    		return dataList;
    	}
    	
    	public void startDocument() throws SAXException 
    	{
    		// TODO Auto-generated method stub
    		dataList = new ArrayList<Book>();
    	}
    	
    	public void startElement(String uri, String localName, String qName,
    			Attributes attributes) throws SAXException 
    	{
    		// TODO Auto-generated method stub
    		if(qName.equals("book"))
    		{
    			book = new Book();
    			book.setName(attributes.getValue("book:name"));
    			book.setId(attributes.getValue("book:id"));
    			book.setPrice(attributes.getValue("book:price"));
    			book.setPublisher(attributes.getValue("book:publisher"));
    			
    		}
    		super.startElement(uri, localName, qName, attributes);
    	}
    
    	@Override
    	public void characters(char[] ch, int start, int length)
    			throws SAXException {
    		// TODO Auto-generated method stub
    		stringBuffer.append(ch,start,length);
    		super.characters(ch, start, length);
    	}
    
    	@Override
    	public void endElement(String uri, String localName, String qName)
    			throws SAXException {
    		// TODO Auto-generated method stub
    		if(qName.equals("book"))
    		{
    			if(stringBuffer.toString()!=null && !stringBuffer.toString().equals(""))
    			{
    				book.setCount(Integer.parseInt(stringBuffer.toString().trim()));
    				stringBuffer.setLength(0);//必须清空缓冲区
    			}
    			dataList.add(book);
    			
    		}
    		super.endElement(uri, localName, qName);
    	}
    }

    SAX引擎须要处理5个分析点,也能够称为分析事件。

    1.開始分析XML文件。

    该分析点表示SAX引擎刚刚開始处理XML文件。可是还没有读取XML文件里的内容,该分析点相应:

    public void startDocument() throws SAXException 
    	{
    		// TODO Auto-generated method stub
    		dataList = new ArrayList<Book>();
    	}

    在此方法里面能够做一些初始化的工作。

    2.開始处理每个XML元素。

    也就是遇到<book>这种起始标记的时候都会触发这个分析节点,所相应的事件方法是startElement。在这个节点能够获得元素的名称、属性的相关信息。

    public void startElement(String uri, String localName, String qName,
    			Attributes attributes) throws SAXException 
    	{
    		// TODO Auto-generated method stub
    		if(qName.equals("book"))
    		{
    			book = new Book();
    			book.setName(attributes.getValue("book:name"));
    			book.setId(attributes.getValue("book:id"));
    			book.setPrice(attributes.getValue("book:price"));
    			book.setPublisher(attributes.getValue("book:publisher"));
    		}
    		super.startElement(uri, localName, qName, attributes);
    	}

    3.处理完每个XML元素。

    也就是遇到</book>这种结束标记的时候会触发endElement方法。在该事件中能够获得当前处理完元素的所有信息。

    	public void endElement(String uri, String localName, String qName)
    			throws SAXException {
    		// TODO Auto-generated method stub
    		if(qName.equals("book"))
    		{
    			if(stringBuffer.toString()!=null && !stringBuffer.toString().equals(""))
    			{
    				book.setCount(Integer.parseInt(stringBuffer.toString().trim()));
    				stringBuffer.setLength(0);//必须清空缓冲区
    			}
    			dataList.add(book);
    		}
    		super.endElement(uri, localName, qName);
    	}

    4.处理完XML文件。假设SAX引擎将整个XML文件所有扫描完就会出发endDocument方法。这种方法可能不是必须的,但在这种方法中能够完毕一些收尾工作。比方说释放资源等。在该例中我没有使用。

    5.读取字符分析点。

    这是一个非常重要的分析点。

    假设没有这个分析点。 前面的工作相当于白做,尽管扫描了XML文件,可是没有保存.....而这个分析点所相应的characters事件方法的主要作用就是保存SAX读取的XML文件内容。

    详细的说就是<book ...  ...>12</book>中的“12”

    public void characters(char[] ch, int start, int length)
    			throws SAXException {
    		// TODO Auto-generated method stub
    		stringBuffer.append(ch,start,length);
    		super.characters(ch, start, length);
    	}

    使用SAX解析XML:

    public class MainActivity extends Activity 
    {
    	private List<Book> books;
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		InputStream inStream = getResources().openRawResource(R.raw.books);
    		BookXMLParser parser = new BookXMLParser();
    		books = ((BookXMLParser)XMLTool.parse(inStream, parser)).getData();
    		
    		if(books!=null && books.size()>0)
    		{
    			for(int i = 0;i<books.size();i++)
    			{
    				Log.d("AAA", books.get(i).toString());
    			}
    		}
    	}
    }


    写XML文件

    public static void WriteXML(List<Book> books, OutputStream out) throws Exception 
    	{
            XmlSerializer serializer = Xml.newSerializer();
            serializer.setOutput(out, "UTF-8");
            serializer.startDocument("UTF-8", true);
            serializer.startTag(null, "books");        
            for (Book book : books) 
            {
                serializer.startTag(null, "book");            
                serializer.attribute(null, "book:name", book.getName());            
                serializer.attribute(null, "book:id",book.getId()); 
                serializer.attribute(null, "book:price", book.getPrice());            
                serializer.attribute(null, "book:publisher",book.getPublisher());          
                serializer.text(String.valueOf(book.getCount()));            
                serializer.endTag(null, "book");
            }        
            serializer.endTag(null, "books");
            serializer.endDocument();
            out.flush();
            out.close();
        }

    Demo:http://download.csdn.net/detail/tangnengwu/7664719

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result
    smarty {for}{forelse}
    整理了一份比较全面的PHP开发编码规范.
    安装SQL server 提示重新启动计算机失败
    使用自定义《UIActivity》进行内容分享-b
    五子棋-b
    iOS面试题16719-b
    iOS 图片填充 UIImageView
    将UIImage保存到iOS照片库和对应程序沙盒中-b
    IOS webview中cookie的读取与保存-b
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4675908.html
Copyright © 2011-2022 走看看