XML编程总结——使用StAX接口操作xml

使用StAX接口操作xml

StAX,全称Streaming API for XML,一种全新的,基于流的JAVA XML解析标准类库。其最终版本于 2004 年 3 月发布,并成为了 JAXP 1.4(将包含在即将发布的 Java 6 中)的一部分。在某种程度上来说,StAX与SAX一样是基于XML事件的解析方式,它们都不会一次性加载整个XML文件。但是它们之间也有很大的不同。

StAX和SAX的区别——拉式解析器和推式解析器的区别

虽然StAX与SAX一样基于XML事件解析,相比于DOM将整个XML加载进内存来说效率高。不同的是,StAX在在处理XML事件的方式上使得应用程序更接近底层,所以在效率上比SAX更优秀。

使用SAX时,我们知道XML事件是由解析器调用开发人员编写的回调方法来处理的,也就是说应用程序是被动于解析器的。应用程序只能被动的等待解析器将XML事件推送给自己处理,对于每一种事件都需要在解析开始之前就做好准备。这种方式被称为“推(push)”。而StAX正好相反,StAX采用一种“拉(pull)”的方式,由应用程序主动从解析器中获取当前XML事件然后根据需求处理(保存或者忽略)。StAX使得应用程序掌握了主动权,可以简化调用代码来准确地处理它预期的内容,或者发生意外时停止解析。此外,由于该方法不基于处理程序回调,应用程序不需要像使用 SAX 那样模拟解析器的状态。

基于指针的API:

基于指针(Cursor)的 API 允许应用程序把 XML 作为一个标记(或事件)流来处理。在这里,解析器就像一跟指针一样在文件流上前进,应用程序可以跟随解析器从文件的开头一直处理到结尾。这是一种低层 API,尽管效率高,但是没有提供底层 XML 结构的抽象。Cursor API 由两个主要API组成,XMLStreamReader和XMLStreamWriter,分别由XMLInputStreamFactory和XMLOutputStreamFactory获取

基于迭代器的API:

基于迭代器的API允许应用程序把 XML 作为一系列事件对象来处理,每个对象和应用程序交换 XML 结构的一部分。应用程序只需要确定解析事件的类型,将其转换成对应的具体类型,然后利用其方法获得属于该事件的信息。基于事件迭代器的方法具有一个基于指针的方法不具备的重要优点。通过将解析器事件变成一级对象,从而让应用程序可以采用面向对象的方式处理它们。这样做有助于模块化和不同应用程序组件之间的代码重用。Iterator API 由两个主要API组成,XMLEventReader和XMLEventWriter,分别由XMLInputStreamFactory和XMLOutputStreamFactory获取

测试代码

public class StAXTest {
    private InputStream is;

    @Before
    public void setUp() throws Exception{
        is=StAXTest.class.getClassLoader()
                .getResourceAsStream("books.xml");
    }

    /**
     * 基于指针的方式读取xml文档——XMLStreamReader
     * @throws Exception
     */
    @Test
    public void testRetrieveByCursor() throws Exception{
        //创建读取流工厂对象
        XMLInputFactory factory = XMLInputFactory.newInstance();
        //创建基于指针的读取流对象
        XMLStreamReader streamReader = factory.createXMLStreamReader(is);
        //用指针迭代
        while(streamReader.hasNext()){
            //事件的ID
            int eventId=streamReader.next();

            switch (eventId) {
            case XMLStreamConstants.START_DOCUMENT:
                System.out.println("start docmuent");
                break;

            case XMLStreamConstants.START_ELEMENT:
                System.out.println("<"+streamReader.getLocalName()+">");
                for(int i=0;i<streamReader.getAttributeCount();i++){
                    System.out.println(streamReader.getAttributeLocalName(i)+
                            "="+streamReader.getAttributeValue(i));
                }
                break;

            case XMLStreamConstants.CHARACTERS:
                if(streamReader.isWhiteSpace()){
                    break;
                }
                System.out.println(streamReader.getText());
                break;
            case XMLStreamConstants.END_ELEMENT:
                System.out.println("</"+streamReader.getLocalName()+">");

                break;
            case XMLStreamConstants.END_DOCUMENT:
                System.out.println("end docmuent");
                break;
            default:
                break;
            }
        }
    }

    /**
     * 基于迭代器的方式读取xml文档——XMLEventReader
     * @throws Exception
     */
    @Test
    public void testRetrieveByIterator() throws Exception{
        //创建读取流工厂对象
        XMLInputFactory factory = XMLInputFactory.newInstance();
        //创建基于迭代器(事件流对象)的流对象
        XMLEventReader eventReader = factory.createXMLEventReader(is);
        //迭代xml文档
        while (eventReader.hasNext()) {
            //得到具体的 事件对象,就是引发事件的对象(可以是元素节点、文本节点、属性节点)
            XMLEvent event = eventReader.nextEvent();

            switch (event.getEventType()) {
            case XMLStreamConstants.START_DOCUMENT:
                System.out.println("start docmuent");
                break;

            case XMLStreamConstants.START_ELEMENT:
                //将事件对象可以转换为元素节点对象
                StartElement element = (StartElement) event;
                System.out.println("<" + element.getName().getLocalPart() + ">");
                for (Iterator it = element.getAttributes(); it.hasNext();) {
                    Attribute attr = (Attribute) it.next();
                    System.out.println(attr.getName().getLocalPart() + "=" + attr.getValue());
                }
                break;

            case XMLStreamConstants.CHARACTERS:
                //将事件对象可以转换成文本节点
                Characters charData = (Characters) event;
                if (charData.isIgnorableWhiteSpace() && charData.isWhiteSpace()) {
                    break;
                }
                System.out.println(charData.getData());
                break;
            case XMLStreamConstants.END_ELEMENT:
                //将事件对象可以转换为元素节点对象
                EndElement endElement = (EndElement) event;
                System.out.println("</" + endElement.getName().getLocalPart() + ">");

                break;
            case XMLStreamConstants.END_DOCUMENT:
                System.out.println("end docmuent");
                break;
            default:
                break;
            }
        }
    }

    /**
     * 基于指针的API输出流——XMLStreamWriter
     * @throws Exception
     */
    @Test
    public void testCreateByCursor() throws Exception{
        //创建输出流对象工厂
        XMLOutputFactory factory = XMLOutputFactory.newInstance();
        //创建输出流对象
        XMLStreamWriter streamWriter = factory.createXMLStreamWriter(System.out);
        //创建xml文档,根据对象方法创建对象元素
        streamWriter.writeStartDocument();
        //book start
        streamWriter.writeStartElement("book");
        streamWriter.writeAttribute("category", "CODING");

        streamWriter.writeStartElement("title");
        streamWriter.writeCharacters("Java Coding");
        streamWriter.writeEndElement();

        streamWriter.writeStartElement("author");
        streamWriter.writeCharacters("lisa");
        streamWriter.writeEndElement();

        streamWriter.writeStartElement("year");
        streamWriter.writeCharacters("2013");
        streamWriter.writeEndElement();

        streamWriter.writeStartElement("price");
        streamWriter.writeCharacters("79.9");
        streamWriter.writeEndElement();

        //book end
        streamWriter.writeEndElement();

        streamWriter.writeEndDocument();
        streamWriter.flush();
    }

    /**
     * 基于迭代器的API输出流——XMLEventWriter
     * @throws Exception
     */
    @Test
    public void testCreateByIterator() throws Exception{
        //创建输出流对象工厂
        XMLOutputFactory factory = XMLOutputFactory.newInstance();
        //创建输出流对象
        XMLEventWriter eventWriter = factory.createXMLEventWriter(System.out);
        //创建xml文档,根据对象方法创建对象元素
        eventWriter.add(new StartDocumentEvent());
        eventWriter.add(new StartElementEvent(new QName("book")));

        eventWriter.add(new StartElementEvent(new QName("title")));
        eventWriter.add(new CharacterEvent("Java Coding"));
        eventWriter.add(new EndElementEvent(new QName("title")));

        eventWriter.add(new StartElementEvent(new QName("author")));
        eventWriter.add(new CharacterEvent("rilay"));
        eventWriter.add(new EndElementEvent(new QName("author")));

        eventWriter.add(new StartElementEvent(new QName("year")));
        eventWriter.add(new CharacterEvent("2008"));
        eventWriter.add(new EndElementEvent(new QName("year")));

        eventWriter.add(new StartElementEvent(new QName("price")));
        eventWriter.add(new CharacterEvent("29.9"));
        eventWriter.add(new EndElementEvent(new QName("price")));

        eventWriter.add(new EndElementEvent(new QName("book")));
        eventWriter.add(new EndDocumentEvent());
        eventWriter.flush();
    }

}

StAX-api 1.0.jar下载路径:

https://download.csdn.net/download/David_XM/20653887

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值