首页 > 技术文章 > xml数据解析和生成

zhisuoyu 2016-03-07 23:36 原文

java中xml的解析方式有许多,有java自带的DOM、SAX,android中的PULL,其它的还有DOM4J、JDOM等。

本文简要讲述DOM、SAX、PULL三种方式。

1.DOM方法

缺点:此方法会将所有数据都读取到内存中,内存消耗大,数据量太大容易造成OOM,而且此方法的效率较低,所以不建议在移动开发中使用。

优点:以树形的结构访问,容易理解,编码简单,可随机访问所需要的内容。

2.SAX方法:

从开头顺序读取直至结尾,读取和处理同步。

缺点:编码难度较大

优点:解析快,占用内存小,适合在移动设备上使用

3.PULL方法:

此方法与SAX方法类似,适合在移动设备中使用,android系统内部默认使用此方法。

与SAX的区别是,此方法能随时结束解析,而SAX不能。


 

先展示一下接下来要解析的xml数据和对应的类:

book.xml

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
    <book id="1">
        <name>冰与火之歌</name>
        <author>乔治马丁</author>
        <year>2014</year>
        <price>89</price>
    </book>
    <book id="2">
        <name>安徒生童话</name>
        <year>2004</year>
        <price>77</price>
        <language>English</language>
    </book>
</bookstore>
View Code

Book.java

public class Book {
    private String id;
    private String name;
    private String author;
    private String year;
    private String price;
    private String language;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    public String getLanguage() {
        return language;
    }

    public void setLanguage(String language) {
        this.language = language;
    }

    @Override
    public String toString() {
        return "Book{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", year='" + year + '\'' +
                ", price='" + price + '\'' +
                ", language='" + language + '\'' +
                '}';
    }
}
View Code

1、PULL

解析:

   public static ArrayList<Book> getBooks(InputStream is) throws Exception {
        ArrayList<Book> books = null;
        Book book = null;
        // 创建一个xml解析的工厂
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        // 获得xml解析类的引用
        XmlPullParser parser = factory.newPullParser();
        parser.setInput(is, "UTF-8");
        // 获得事件的类型
        int eventType = parser.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT) {
            switch (eventType) {
                case XmlPullParser.START_DOCUMENT:
                    books = new ArrayList<>();
                    break;
                case XmlPullParser.START_TAG:
                    if ("book".equals(parser.getName())) {
                        book = new Book();
                        // 取出属性值
                        String id = parser.getAttributeValue(0);
                        book.setId(id);
                    } else if ("name".equals(parser.getName())) {
                        String name = parser.nextText();// 获取该节点的内容
                        Show.log("name:"+name);
                        book.setName(name);
                    } else if ("author".equals(parser.getName())) {
                        String author = parser.nextText();
                        book.setAuthor(author);
                    }else if("year".equals(parser.getName())){
                        String year=parser.nextText();
                        book.setYear(year);
                    }else if ("price".equals(parser.getName())){
                        String price=parser.nextText();
                        book.setPrice(price);
                    }else if("language".equals(parser.getName())){
                        String language=parser.nextText();
                        book.setLanguage(language);
                    }
                    break;
                case XmlPullParser.END_TAG:
                    if ("book".equals(parser.getName())) {
                        books.add(book);
                        book = null;
                    }
                    break;
            }
            eventType = parser.next();
        }
        return books;
    }

 

生成:

    public static void save(List<Book> books, OutputStream out) throws Exception {
        XmlSerializer serializer = Xml.newSerializer();
        serializer.setOutput(out, "UTF-8");
        serializer.startDocument("UTF-8", true);
        serializer.startTag(null, "bookstore");
        for (Book book : books) {
            Show.log(book.toString());
            serializer.startTag(null, "book");
            serializer.attribute(null, "id", book.getId() + "");

            serializer.startTag(null, "name");
            serializer.text(book.getName());
            serializer.endTag(null, "name");

            serializer.startTag(null, "author");
            serializer.text(book.getAuthor() + "");
            serializer.endTag(null, "author");

            serializer.startTag(null,"year");
            serializer.text(book.getYear());
            serializer.endTag(null,"year");

            serializer.startTag(null,"language");
            serializer.text(book.getLanguage()+"");
            serializer.endTag(null,"language");

            serializer.endTag(null, "book");
        }

        serializer.endTag(null, "bookstore");
        serializer.endDocument();
    }

 


 

 

2、DOM

解析:

    public static void domXmlParser() {
        ArrayList<Book> bookLists = new ArrayList<Book>();
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document document = db.parse("book.xml");
            NodeList bookList = document.getElementsByTagName("book");
            for (int i = 0; i < bookList.getLength(); i++) {
                Node book = bookList.item(i);
                Book bookEntity = new Book();
                NamedNodeMap attrs = book.getAttributes();
                for (int j = 0; j < attrs.getLength(); j++) {
                    Node attr = attrs.item(j);
                    if (attr.getNodeName().equals("id")) {
                        bookEntity.setId(attr.getNodeValue());
                    }
                }
                NodeList childNodes = book.getChildNodes();
                for (int k = 0; k < childNodes.getLength(); k++) {
                    if (childNodes.item(k).getNodeType() == Node.ELEMENT_NODE) {
                        String name = childNodes.item(k).getNodeName();
                        String value = childNodes.item(k).getFirstChild().getNodeValue();
                        if (name.equals("name")) {
                            bookEntity.setName(value);
                        }
                        else if (name.equals("author")) {
                            bookEntity.setAuthor(value);
                        }
                        else if (name.equals("year")) {
                            bookEntity.setYear(value);
                        }
                        else if (name.equals("price")) {
                            bookEntity.setPrice(value);
                        }
                        else if (name.equals("language")) {
                            bookEntity.setLanguage(value);
                        }
                    }
                }
                bookLists.add(bookEntity);
                bookEntity = null;
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

 

生成:

    public void DOMCreateXML() {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = null;
        try {
            db = dbf.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
        Document document = db.newDocument();
        document.setXmlStandalone(true);
        Element bookstore = document.createElement("bookStore");
        Element book = document.createElement("book");
        Element name = document.createElement("name");
        name.setTextContent("小王子");
        book.appendChild(name);
        book.setAttribute("id", "1");
        bookstore.appendChild(book);
        document.appendChild(bookstore);
        TransformerFactory tff = TransformerFactory.newInstance();
        try {
            Transformer tf = tff.newTransformer();
            tf.setOutputProperty(OutputKeys.INDENT, "yes");
            tf.transform(new DOMSource(document), new StreamResult(new File(
                    "books1.xml")));
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
    }

 

3、SAX

 解析:

public class SAXParserHandler extends DefaultHandler {
    String value = null;
    Book book = null;
    private ArrayList<Book> bookList = new ArrayList<Book>();
    public ArrayList<Book> getBookList() {
        return bookList;
    }

    int bookIndex = 0;
    /**
     * 用来标识解析开始
     */
    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
    }
    
    /**
     * 用来标识解析结束
     */
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }
    
    /**
     * 解析xml元素
     */
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
        if (qName.equals("book")) {
            bookIndex++;
            book = new Book();
            String value = attributes.getValue("id");
            int num = attributes.getLength();
            for(int i = 0; i < num; i++){
                if (attributes.getQName(i).equals("id")) {
                    book.setId(attributes.getValue(i));
                }
            }
        }
    }
    
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        super.endElement(uri, localName, qName);
        if (qName.equals("book")) {
            bookList.add(book);
            book = null;
        }
        else if (qName.equals("name")) {
            book.setName(value);
        }
        else if (qName.equals("author")) {
            book.setAuthor(value);
        }
        else if (qName.equals("year")) {
            book.setYear(value);
        }
        else if (qName.equals("price")) {
            book.setPrice(value);
        }
        else if (qName.equals("language")) {
            book.setLanguage(value);
        }
    }
    
    
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        // TODO Auto-generated method stub
        super.characters(ch, start, length);
        String temp = new String(ch, start, length);
        if (!temp.trim().equals("")) {
            value = temp;
        }
    }
}
    public static void saxXmlParser(){
        SAXParserFactory factory = SAXParserFactory.newInstance();
        try {
            SAXParser parser = factory.newSAXParser();
            SAXParserHandler handler = new SAXParserHandler();
            parser.parse("book.xml", handler);
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

生成:

    public void SAXCreateXML() {
        SAXTransformerFactory tff = (SAXTransformerFactory) SAXTransformerFactory
                .newInstance();
        try {
            TransformerHandler handler = tff.newTransformerHandler();
            Transformer tr = handler.getTransformer();
            tr.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            tr.setOutputProperty(OutputKeys.INDENT, "yes");
            File f = new File("books2.xml");
            if (!f.exists()) {
                f.createNewFile();
            }
            Result result = new StreamResult(new FileOutputStream(f));
            handler.setResult(result);
            handler.startDocument();
            AttributesImpl attr = new AttributesImpl();
            handler.startElement("", "", "bookstore", attr);
            attr.clear();
            attr.addAttribute("", "", "id", "", "1");
            handler.startElement("", "", "book", attr);
            attr.clear();
            handler.startElement("", "", "name", attr);
            handler.characters("小王子".toCharArray(), 0, "小王子".length());
            handler.endElement("", "", "name");
        
            handler.endElement("", "", "book");
            handler.endElement("", "", "bookstore");
            handler.endDocument();

        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        }
    }

 

推荐阅读