在java中应用sax解析xml

    添加时间:2013-5-3 点击量:

    在java中,原生解析xml文档的体式格式有两种,分别是:Dom解析和Sax解析


    Dom解析功能强大,可增删改查,操纵时会将xml文档以文档对象的体式格式读取到内存中,是以实用于小文档


    Sax解析是从头到尾逐行逐个元素读取内容,批改较为不便,但实用于只读的大文档


    本文首要讲解Sax解析,其余放在后面



    Sax采取事务驱动的体式格式解析文档。简单点说,如同在电影院看电影一样,从头到尾看一遍就完了,不克不及回退(Dom可交游返回读取)


    在看电影的过程中,每碰到一个情节,一段泪水,一次擦肩,你都邑调动大脑和神经去接管或处理惩罚这些信息


    同样,在Sax的解析过程中,读取到文档开首、结尾,元素的开首和结尾都邑触发一些回调办法,你可以在这些回调办法中进行响应事务处理惩罚


    这四个办法是:startDocument() 、 endDocument()、 startElement()、 endElement


    此外,光读取到节点处是不敷的,我们还须要characters()办法来细心处理惩罚元素内包含的内容


    将这些回调办法凑集起来,便形成了一个类,这个类也就是我们须要的触发器


    一般从Main办法中读取文档,却在触发器中处理惩罚文档,这就是所谓的事务驱动解析办法



    如上图,在触发器中,起首开端读取文档,然后开端逐个解析元素,每个元素中的内容会返回到characters()办法


    接着停止元素读取,所有元素读取完后,停止文档解析



    如今我们开端创建触发器这个类,要创建这个类起首须要持续DefaultHandler


    创建SaxHandler,并覆写响应办法:



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


    public class SaxHandler extends DefaultHandler {

    / 此办法有三个参数
    arg0是传回来的字符数组,其包含元素内容
    arg1和arg2分别是数组的开端地位和停止地位 /
    @Override
    public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
    String content = new String(arg0, arg1, arg2);
    System.out.println(content);
    super.characters(arg0, arg1, arg2);
    }

    @Override
    public void endDocument() throws SAXException {
    System.out.println(\n…………停止解析文档…………);
    super.endDocument();
    }

    / arg0是名称空间
    arg1是包含名称空间的标签,若是没有名称空间,则为空
    arg2是不包含名称空间的标签 /
    @Override
    public void endElement(String arg0, String arg1, String arg2)
    throws SAXException {
    System.out.println(停止解析元素 + arg2);
    super.endElement(arg0, arg1, arg2);
    }

    @Override
    public void startDocument() throws SAXException {
    System.out.println(…………开端解析文档…………\n);
    super.startDocument();
    }

    /arg0是名称空间
    arg1是包含名称空间的标签,若是没有名称空间,则为空
    arg2是不包含名称空间的标签
    arg3很明显是属性的凑集 /
    @Override
    public void startElement(String arg0, String arg1, String arg2,
    Attributes arg3) throws SAXException {
    System.out.println(开端解析元素 + arg2);
    if (arg3 != null) {
    for (int i = 0; i < arg3.getLength(); i++) {
    // getQName()是获取属性名称,
    System.out.print(arg3.getQName(i) + =\ + arg3.getValue(i) + \);
    }
    }
    System.out.print(arg2 + :);
    super.startElement(arg0, arg1, arg2, arg3);
    }
    }


    XML文档:



    <?xml version=1.0 encoding=UTF-8?> 
    
    <books>
    <book id=001>
    <title>Harry Potter</title>
    <author>J K. Rowling</author>
    </book>
    <book id=002>
    <title>Learning XML</title>
    <author>Erik T. Ray</author>
    </book>
    </books>


     TestDemo测试类:



    import java.io.File;
    

    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;


    public class TestDemo {

    public static void main(String[] args) throws Exception {
    // 1.实例化SAXParserFactory对象
    SAXParserFactory factory = SAXParserFactory.newInstance();
    // 2.创建解析器
    SAXParser parser = factory.newSAXParser();
    // 3.获取须要解析的文档,生成解析器,最后解析文档
    File f = new File(books.xml);
    SaxHandler dh = new SaxHandler();
    parser.parse(f, dh);
    }
    }


     输出成果:



    …………开端解析文档…………
    

    开端解析元素 books
    books:

    开端解析元素 book
    id=001book:

    开端解析元素 title
    title:Harry Potter
    停止解析元素 title


    开端解析元素 author
    author:J K. Rowling
    停止解析元素 author


    停止解析元素 book


    开端解析元素 book
    id=002book:

    开端解析元素 title
    title:Learning XML
    停止解析元素 title


    开端解析元素 author
    author:Erik T. Ray
    停止解析元素 author


    停止解析元素 book


    停止解析元素 books

    …………停止解析文档…………



    上方的固然正确显示了履行流程,然则输出却很乱


    为了加倍清楚的履行此流程,我们还可以重写SaxHandler,使其将本来的xml文档还原一遍


    重写的SaxHandler类:



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


    public class SaxHandler extends DefaultHandler {

    @Override
    public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
    System.out.print(new String(arg0, arg1, arg2));
    super.characters(arg0, arg1, arg2);
    }

    @Override
    public void endDocument() throws SAXException {
    System.out.println(\n停止解析);
    super.endDocument();
    }

    @Override
    public void endElement(String arg0, String arg1, String arg2)
    throws SAXException {
    System.out.print(</);
    System.out.print(arg2);
    System.out.print(>);
    super.endElement(arg0, arg1, arg2);
    }

    @Override
    public void startDocument() throws SAXException {
    System.out.println(开端解析);
    String s = <?xml version=\1.0\ encoding=\UTF-8\?>;
    System.out.println(s);
    super.startDocument();
    }

    @Override
    public void startElement(String arg0, String arg1, String arg2,
    Attributes arg3) throws SAXException {

    System.out.print(<);
    System.out.print(arg2);

    if (arg3 != null) {
    for (int i = 0; i < arg3.getLength(); i++) {
    System.out.print( + arg3.getQName(i) + =\ + arg3.getValue(i) + \);
    }
    }
    System.out.print(>);
    super.startElement(arg0, arg1, arg2, arg3);
    }

    }


     履行成果:



    如今看起来很多多少了,将其还原更能充沛申明其解析流程





    我们永远不要期待别人的拯救,只有自己才能升华自己。自己已准备好了多少容量,方能吸引对等的人与我们相遇,否则再美好的人出现、再动人的事情降临身边,我们也没有能量去理解与珍惜,终将擦肩而过。—— 姚谦《品味》
    分享到: