Java Stax操作XML简介

使用stax操作xml 非常的简单,它的读取过程像是一个光标在移动。针对不同的节点做不同的处理。
先看一个基于光标的模型处理xml:

public class StaxTest {

    @Test
    public void test1() {
        try {
            // 1.构建XMLStreamReader
            XMLInputFactory factory = XMLInputFactory.newInstance();
            XMLStreamReader reader = factory
                    .createXMLStreamReader(StaxTest.class
                            .getResourceAsStream("books.xml"));
            while (reader.hasNext()) {
                int type = reader.next();
                //是否是开始节点,开始节点就是<>
                if(type==XMLStreamReader.START_ELEMENT){
                    System.out.println("<"+reader.getName()+">");
                    //是否是文本节点,开始节点和结束节点之间的内容
                }else if(type==XMLStreamReader.CHARACTERS){
                    System.out.println(reader.getText());
                    //是否是结束节点,结束节点就是</>
                }else if(type==XMLStreamReader.END_ELEMENT){
                    System.out.println("</"+reader.getName()+">");
                }
            }
        } catch (FactoryConfigurationError | XMLStreamException e) {
            e.printStackTrace();
        }
    }
    @Test
    public void test2() {
        try {
            // 1.构建XMLStreamReader
            XMLInputFactory factory = XMLInputFactory.newInstance();
            XMLStreamReader reader = factory
                    .createXMLStreamReader(StaxTest.class
                            .getResourceAsStream("books.xml"));
            while (reader.hasNext()) {
                int type = reader.next();
                //输出所有book节点的属性,0表示是第几个参数
                if(type==XMLStreamReader.START_ELEMENT){
                    if (reader.getName().toString().equals("book")) {
                        System.out.println(reader.getAttributeName(0) + ":"
                                + reader.getAttributeValue(0));
                    }
                }
            }
        } catch (FactoryConfigurationError | XMLStreamException e) {
            e.printStackTrace();
        }
    }
    @Test
    public void test3() {
        try {
            // 1.构建XMLStreamReader
            XMLInputFactory factory = XMLInputFactory.newInstance();
            XMLStreamReader reader = factory
                    .createXMLStreamReader(StaxTest.class
                            .getResourceAsStream("books.xml"));
            while (reader.hasNext()) {
                int type = reader.next();
                //输出每本书的名称和价格,
                if(type==XMLStreamReader.START_ELEMENT){
                    if (reader.getName().toString().equals("name")) {
                        System.out.print(reader.getName()+":"+reader.getElementText());
                    }
                    if (reader.getName().toString().equals("price")) {
                        System.out.println(reader.getName()+":"+reader.getElementText());
                    }
                }
            }
        } catch (FactoryConfigurationError | XMLStreamException e) {
            e.printStackTrace();
        }
    }
}
<books>
    <book category="编程技术" edition="8">
        <id>1</id>
        <name>Java编程思想</name>
        <price>80</price>
        <author>张三</author>
        <detail>
             <pressTime>天朝</pressTime>
             <storyTime>21世纪</storyTime>
        </detail>
    </book>
    <book category="历史小说" edition="1">
        <id>2</id>
        <name>三国演义</name>
        <price>30</price>
        <author>罗贯中</author>
        <detail>
             <pressTime>明朝</pressTime>
             <storyTime>汉末</storyTime>
        </detail>
    </book>
    <book category="小说" edition="2">
        <id>3</id>
        <name>红楼梦</name>
        <price>35</price>
        <author>曹雪芹</author>
        <detail>
             <pressTime>清朝</pressTime>
             <storyTime>不详</storyTime>
        </detail>
    </book>
    <book category="神话小说" edition="4">
        <id>4</id>
        <name>西游记</name>
        <price>25</price>
        <author>吴承恩</author>
        <detail>
             <pressTime>明朝</pressTime>
             <storyTime>大唐</storyTime>
        </detail>
    </book>
    <book category="小说" edition="5">
        <id>5</id>
        <name>水浒传</name>
        <price>30</price>
        <author>施耐庵</author>
        <detail>
             <pressTime>明朝</pressTime>
             <storyTime>大宋</storyTime>
        </detail>
    </book>
</books>

还有一种处理方式是基于迭代模型的处理方式,基于迭代模型与基于光标模型非常相似,看代码:

    @Test
    public void test4(){
        try {
            XMLInputFactory factory = XMLInputFactory.newInstance();
            XMLEventReader reader = factory.createXMLEventReader(StaxTest.class.getResourceAsStream("books.xml"));
            while(reader.hasNext()){
                XMLEvent event = reader.nextEvent();
                if(event.isStartElement()){
                    System.out.println("<"+event.asStartElement().getName()+">");
                }else if(event.isCharacters()){
                    System.out.println(event.asCharacters().getData());
                }else if(event.isEndElement()){
                    System.out.println("</"+event.asEndElement().getName()+">");
                }
            }
        } catch (FactoryConfigurationError | XMLStreamException e) {
            e.printStackTrace();
        }

    }

这一段代码输出结果与test1()输出结果完全相同,基于迭代模型就是要先将event.as****,然后操作与基于光标模型完全相同。

再看看给迭代模型添加过滤器,

    @Test
    public void test5() {
        try {
            XMLInputFactory factory = XMLInputFactory.newInstance();
            XMLEventReader reader = factory.createFilteredReader(factory
                    .createXMLEventReader(StaxTest.class
                            .getResourceAsStream("books.xml")), (event) -> {
                                if(event.isStartElement()) return true;
                return false;
            });
            while(reader.hasNext()){
                XMLEvent event = reader.nextEvent();
                System.out.println(event.asStartElement().getName());
            }
        } catch (FactoryConfigurationError | XMLStreamException e) {
            e.printStackTrace();
        }
    }

上面这一段给迭代模型添加了一个过滤器,这里是用到了jdk8的最新特性lambda表达式来简化了操作,过滤器返回所有的开始节点。

posted @ 2015-05-09 16:30  江南一点雨  阅读(2371)  评论(0编辑  收藏  举报