砸锅工厂

磨剪子嘞~~~ 戗菜刀~

JAVA解析XML文件
.xml文件,树形结构

标准XML文档示例:

<?xml version="1.0" encoding="UTF-8"?>
<bookStore>
    <book id="1">
            <name>冰与火之歌</name>
            <author>乔治马丁</author>
            <year>2014</year>
            <price>99</price>
    </book>
    <book id="2">
            <name>秦腔</name>
            <author>贾平凹</author>
            <price>90</price>
    </book>
</bookStore>

Why?:
1、不同应用程序之间的通信问题(订票软件和支付软件);
2、不同平台间的通信(MAC和windows);
3、不同平台间共享数据(PC端和移动端)

JAVA读取XML(解析)
目的:
获取节点名、节点值、属性名、属性值。解析后JAVA程序能够得到XML文件的所有数据

四种方式:
DOM(官方)
SAX(官方)
DOM4J(需要导jar包)
JDOM(需要导jar包)

books.xml文件练习:
DOM解析
将xml文件全部加载到内存,然后逐个解析。

常用节点类型
这里写图片描述

解析方法:

package DomTest;

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class DOMTest {

    public static void main(String[] args) {
        // 创建一个DocumentBuilderFactory对象
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        // 创建一个DocumentBuilder的对象
        try {
            // 创建DocumentBuilder对象
            DocumentBuilder db = dbf.newDocumentBuilder();
            // 通过DocumentBuilder对象的parse方法加载books.xml文件
            // 到当前项目下
            Document document = db.parse("books.xml");
            // 获取所有book节点的集合
            NodeList bookList = document.getElementsByTagName("book");
            //通过nodeList的getLength()方法获取bookLIst的长度
            System.out.println("一共有:"+bookList.getLength()+"本书");
            //便利各个book节点
            for (int i = 0; i < bookList.getLength(); i++) {
                System.out.println("开始遍历第"+(i+1)+"本书");
                //通过 item(i)获取一个book节点,nodeList
                Node book=bookList.item(i);
                //获取book的属性的集合
                NamedNodeMap attrs=book.getAttributes();
                System.out.println("第"+(i+1)+"本书共有"+attrs.getLength()+"个属性");
                //便利book的属性
                for (int j = 0; j < attrs.getLength(); j++) {
                    //通过item()方法获取book节点的某一个属性
                    Node attr=attrs.item(j);
                    //获取属性名
                    System.out.println("属性名:"+attr.getNodeName());
                    //获取属性值
                    System.out.println("属性值:"+attr.getNodeValue());
                }
                System.out.println("结束遍历第"+(i+1)+"本书");
            }

        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
    }

}

输出:
一共有:2本书
开始遍历第1本书
第1本书共有1个属性
属性名:id
属性值:1
结束遍历第1本书
开始遍历第2本书
第2本书共有1个属性
属性名:id
属性值:2
结束遍历第2本书

已知节点属性名称的情况下的遍历:

package DomTest;

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class DOMTest {

    public static void main(String[] args) {
        // 创建一个DocumentBuilderFactory对象
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        // 创建一个DocumentBuilder的对象
        try {
            // 创建DocumentBuilder对象
            DocumentBuilder db = dbf.newDocumentBuilder();
            // 通过DocumentBuilder对象的parse方法加载books.xml文件
            // 到当前项目下
            Document document = db.parse("books.xml");
            // 获取所有book节点的集合
            NodeList bookList = document.getElementsByTagName("book");
            //通过nodeList的getLength()方法获取bookLIst的长度
            System.out.println("一共有:"+bookList.getLength()+"本书");
            //便利各个book节点
            for (int i = 0; i < bookList.getLength(); i++) {
                System.out.println("++++++++++++开始遍历第"+(i+1)+"本书+++++++++++");
                //方式一,不知道有多少节点,通过循环来遍历所有节点。

//              //通过 item(i)获取一个book节点,nodeList
//              Node book=bookList.item(i);
//              //获取book的属性的集合
//              NamedNodeMap attrs=book.getAttributes();
//              System.out.println("第"+(i+1)+"本书共有"+attrs.getLength()+"个属性");
//              //便利book的属性
//              for (int j = 0; j < attrs.getLength(); j++) {
//                  //通过item()方法获取book节点的某一个属性
//                  Node attr=attrs.item(j);
//                  //获取属性名
//                  System.out.println("属性名:"+attr.getNodeName());
//                  //获取属性值
//                  System.out.println("属性值:"+attr.getNodeValue());
//              }


                //方式二,知道有且只有一个节点。并且知道属性的名称为“id”
                //强制类型转换将book节点类型转换为Element类型
                Element book =(Element) bookList.item(i);

                //通过getAttribute(“id”)方法获取到属性的值
                String attrValue=book.getAttribute("id");
                System.out.println("id的属性的属性值为"+attrValue);

//              //解析book节点的子节点,需要用到方式一中创建的book对象
//              //获取子节点的集合
//              NodeList childNodes=book.getChildNodes();
//              
//              //遍历childNodes获取每个子节点的节点名和节点值
//              System.out.println("第"+(i+1)+"本书共有"+childNodes.getLength()+"个子节点");
//              
                System.out.println("++++++++++++结束遍历第"+(i+1)+"本书++++++++++++");
            }

        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
    }

}

输出:
一共有:2本书
++++++++++++开始遍历第1本书+++++++++++
id的属性的属性值为1
++++++++++++结束遍历第1本书++++++++++++
++++++++++++开始遍历第2本书+++++++++++
id的属性的属性值为2
++++++++++++结束遍历第2本书++++++++++++

解析book节点下的所有子节点:

package DomTest;

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class DOMTest {

    public static void main(String[] args) {
        // 创建一个DocumentBuilderFactory对象
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        // 创建一个DocumentBuilder的对象
        try {
            // 创建DocumentBuilder对象
            DocumentBuilder db = dbf.newDocumentBuilder();
            // 通过DocumentBuilder对象的parse方法加载books.xml文件
            // 到当前项目下
            Document document = db.parse("books.xml");
            // 获取所有book节点的集合
            NodeList bookList = document.getElementsByTagName("book");
            //通过nodeList的getLength()方法获取bookLIst的长度
            System.out.println("一共有:"+bookList.getLength()+"本书");
            //便利各个book节点
            for (int i = 0; i < bookList.getLength(); i++) {
                System.out.println("++++++++++++开始遍历第"+(i+1)+"本书+++++++++++");
                //方式一,不知道有多少节点,通过循环来遍历所有节点。

                //通过 item(i)获取一个book节点,nodeList
                Node book=bookList.item(i);
                //获取book的属性的集合
                NamedNodeMap attrs=book.getAttributes();
                System.out.println("第"+(i+1)+"本书共有"+attrs.getLength()+"个属性");
                //便利book的属性
                for (int j = 0; j < attrs.getLength(); j++) {
                    //通过item()方法获取book节点的某一个属性
                    Node attr=attrs.item(j);
                    //获取属性名
                    System.out.println("属性名:"+attr.getNodeName());
                    //获取属性值
                    System.out.println("属性值:"+attr.getNodeValue());
                }


//              //方式二,知道有且只有一个节点。并且知道属性的名称为“id”
//              //强制类型转换将book节点类型转换为Element类型
//              Element book =(Element) bookList.item(i);
//              
//              //通过getAttribute(“id”)方法获取到属性的值
//              String attrValue=book.getAttribute("id");
//              System.out.println("id的属性的属性值为"+attrValue);


                //解析book节点的子节点,需要用到方式一中创建的book对象
                //获取子节点的集合
                NodeList childNodes=book.getChildNodes();

                //遍历childNodes获取每个子节点的节点名和节点值
                System.out.println("第"+(i+1)+"本书共有"+childNodes.getLength()+"个子节点");
                //循环遍历
                for (int j = 0; j < childNodes.getLength(); j++) {
                    //区分text类型的node和element类型的node
                    if(childNodes.item(j).getNodeType()==Node.ELEMENT_NODE){
                        //输出了element类型节点的节点名
                        System.out.println("第"+(j+1)+"个节点名:"+childNodes.item(j).getNodeName());
                        //输出element类型节点的节点值
                        //需先获取当前节点的首个子节点,否则获取的是《name》标签的值NULL

                        //方式一:如果<name>节点下有多个子节点,此方法只输出确定的某个子节点的值
                        //同样要注意,<name>节点的第一个子节点的值是第一子节点的类型的值,还是NULL
                        System.out.println("节点值为:"+childNodes.item(j).getFirstChild()
                                .getNodeValue());
                        //方式二:如果<name>节点下有多个子节点,此方法输出所有子节点的text
                        System.out.println(childNodes.item(j).getTextContent());
                    }

                }

                System.out.println("++++++++++++结束遍历第"+(i+1)+"本书++++++++++++");
            }

        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
    }

}

输出:
一共有:2本书
++++++++++++开始遍历第1本书+++++++++++
第1本书共有1个属性
属性名:id
属性值:1
第1本书共有9个子节点
第2个节点名:name
节点值为:冰与火之歌
冰与火之歌
第4个节点名:author
节点值为:乔治马丁
乔治马丁
第6个节点名:year
节点值为:2014
2014
第8个节点名:price
节点值为:99
99
++++++++++++结束遍历第1本书++++++++++++
++++++++++++开始遍历第2本书+++++++++++
第2本书共有1个属性
属性名:id
属性值:2
第2本书共有7个子节点
第2个节点名:name
节点值为:秦腔
秦腔
第4个节点名:author
节点值为:贾平凹
贾平凹
第6个节点名:price
节点值为:90
90
++++++++++++结束遍历第2本书++++++++++++

SAX解析XML文件
通过自己创建的一个Handler类,由外向内顺序逐个解析。

初步解析:
步骤:
1、通过SAXParseFactory的静态newInstance()方法获取SAXParseFactory实例factory
2、通过SAXParserFactory实例的newSAXParser()方法返回SAXParse实例parser
3、创建一个类继承DefaultHandler,重写其中的一些方法进行业务处理并创建这个类的实例handler
重写两个方法:
startElement()
endElement()

SAXParserHandler:

package test2;

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

public class SAXParserHandler extends DefaultHandler {
    /***
     * 遍历xml的开始标签
     */
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        // TODO Auto-generated method stub
        super.startElement(uri, localName, qName, attributes);
    }

    /***
     * 遍历xml的结束标签
     */
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        // TODO Auto-generated method stub
        super.endElement(uri, localName, qName);
    }

    /***
     * 标识解析开始
     */
    @Override
    public void startDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.startDocument();
        System.out.println("SAX解析开始");
    }

    /***
     * 标识解析结束
     */
    @Override
    public void endDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.endDocument();
        System.out.println("SAX解析结束");
    }
}

SAXTest.java:

package test;

import java.io.IOException;

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

import org.xml.sax.SAXException;

import test2.SAXParserHandler;

public class SAXTest {

    public static void main(String[] args) {
        // 通过SAXParseFactory的静态newInstance()
        //方法获取SAXParseFactory实例factory
        SAXParserFactory factory=SAXParserFactory.newInstance();

        //通过SAXParserFactory实例的newSAXParser()
        //方法返回SAXParse实例parser
        try {
            SAXParser parser= factory.newSAXParser();
            //创建SAXParserHandler对象
            SAXParserHandler handler=new SAXParserHandler();            
            parser.parse("books.xml", handler);
        } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();            
        } catch (ParserConfigurationException | SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

运行输出:
SAX解析开始
SAX解析结束

解析节点属性:

package test2;

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

import test3.Book;

public class SAXParserHandler extends DefaultHandler {

    int bookIndex=0;//显示是第几本书的变量

    /***
     * 遍历xml的开始标签
     */
    @Override
    public void startElement(String uri, String localName, String qName, 
            Attributes attributes) throws SAXException {
        // TODO Auto-generated method stub
        //调用DefaultHandler类的startElement方法
        super.startElement(uri, localName, qName, attributes);
        //开始解析book元素的属性
        if (qName.equals("book")) {         
            bookIndex++;
            System.out.println("开始遍历第"+bookIndex+"本书");
//          //方法一:已知book元素下属性的名称,根据属性名称获取属性的值。
//          String value=attributes.getValue("id");
//          System.out.println("book的属性值为:"+value);

            //方法二:book元素下舒心规定名称个数未知的情况
            int num=attributes.getLength();
            for (int i = 0; i < num; i++) {
                System.out.println("book元素的第"+(i+1)
                        +"个属性名:"+attributes.getQName(i));
                System.out.println("book元素的第"+(i+1)
                        +"个属性值:"+attributes.getValue(i));

                if (attributes.getQName(i).equals("id")) {
                    book.setId(attributes.getValue(i));
                }
            }
        }else if(!qName.equals("book")&&!qName.equals("bookStore")){
            System.out.print("节点名是:"+qName);
        }

        //qName.equals("name")时,向book中setName()
    }

    /***
     * 遍历xml的结束标签
     */
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        // TODO Auto-generated method stub
        super.endElement(uri, localName, qName);
        //判断是否针对一本书遍历结束
                if (qName.equals("book")) { 

                    System.out.println("遍历结束");
                    System.out.println("结束遍历第"+bookIndex+"本书");
                    System.out.println();
                }
    }

    /***
     * 标识解析开始
     */
    @Override
    public void startDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.startDocument();

        System.out.println("SAX解析开始");
    }

    /***
     * 标识解析结束
     */
    @Override
    public void endDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.endDocument();
        System.out.println("SAX解析结束");
    }

    /***
     * ch 节点中的所有内容
     * start 开始的节点
     *  
     */
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        // TODO Auto-generated method stub
        super.characters(ch, start, length);
        String value=new String(ch,start,length);
        if (!value.trim().equals("")) {         
            System.out.println("\t节点值是:"+value);
        }
    }
}

输出:
SAX解析开始
开始遍历第1本书
book元素的第1个属性名:id
book元素的第1个属性值:1
节点名是:name 节点值是:冰与火之歌
节点名是:author 节点值是:乔治马丁
节点名是:year 节点值是:2014
节点名是:price 节点值是:99
遍历结束
结束遍历第1本书

开始遍历第2本书
book元素的第1个属性名:id
book元素的第1个属性值:2
节点名是:name 节点值是:秦腔
节点名是:author 节点值是:贾平凹
节点名是:price 节点值是:90
遍历结束
结束遍历第2本书

SAX解析结束

解析并存储XML结构:
新建Book类

package test3;

public class Book {
    private String id;
    private String name;
    private String author;
    private String year;
    private String price;
    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 autor) {
        this.author = autor;
    }
    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;
    }   
}

修改SAXParserHandler:

package test2;

import java.util.ArrayList;

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

import test3.Book;

public class SAXParserHandler extends DefaultHandler {

    int bookIndex=0;//显示是第几本书的变量
    //将character()中的value定义为全局变量
    String value=null;
    Book book=null;
    private ArrayList<Book> bookList=new ArrayList<Book>();
    public ArrayList<Book> getBookList(){
        return bookList;
    }
    /***
     * 遍历xml的开始标签
     */
    @Override
    public void startElement(String uri, String localName, String qName, 
            Attributes attributes) throws SAXException {
        // TODO Auto-generated method stub
        //调用DefaultHandler类的startElement方法
        super.startElement(uri, localName, qName, attributes);
        //开始解析book元素的属性
        if (qName.equals("book")) {
            book=new Book();
            bookIndex++;
            System.out.println("开始遍历第"+bookIndex+"本书");
//          //方法一:已知book元素下属性的名称,根据属性名称获取属性的值。
//          String value=attributes.getValue("id");
//          System.out.println("book的属性值为:"+value);

            //方法二:book元素下舒心规定名称个数未知的情况
            int num=attributes.getLength();
            for (int i = 0; i < num; i++) {
                System.out.println("book元素的第"+(i+1)
                        +"个属性名:"+attributes.getQName(i));
                System.out.println("book元素的第"+(i+1)
                        +"个属性值:"+attributes.getValue(i));

                if (attributes.getQName(i).equals("id")) {
                    book.setId(attributes.getValue(i));
                }
            }
        }else if(!qName.equals("book")&&!qName.equals("bookStore")){
            System.out.print("节点名是:"+qName);
        }

        //qName.equals("name")时,向book中setName()
    }

    /***
     * 遍历xml的结束标签
     */
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        // TODO Auto-generated method stub
        super.endElement(uri, localName, qName);
        //判断是否针对一本书遍历结束
                if (qName.equals("book")) { 
                    bookList.add(book);
                    book=null;
                    System.out.println("遍历结束");
                    System.out.println("结束遍历第"+bookIndex+"本书");
                    System.out.println();
                }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);
                }
    }

    /***
     * 标识解析开始
     */
    @Override
    public void startDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.startDocument();

        System.out.println("SAX解析开始");
    }

    /***
     * 标识解析结束
     */
    @Override
    public void endDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.endDocument();
        System.out.println("SAX解析结束");
    }

    /***
     * ch 节点中的所有内容
     * start 开始的节点
     *  
     */
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        // TODO Auto-generated method stub
        super.characters(ch, start, length);
        value=new String(ch,start,length);
        if (!value.trim().equals("")) {         
            System.out.println("\t节点值是:"+value);
        }
    }
}

修改SAXTest:

package test;

import java.io.IOException;

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

import org.xml.sax.SAXException;

import test2.SAXParserHandler;
import test3.Book;

public class SAXTest {

    public static void main(String[] args) {
        // 通过SAXParseFactory的静态newInstance()
        //方法获取SAXParseFactory实例factory
        SAXParserFactory factory=SAXParserFactory.newInstance();

        //通过SAXParserFactory实例的newSAXParser()
        //方法返回SAXParse实例parser
        try {
            SAXParser parser= factory.newSAXParser();
            //创建SAXParserHandler对象
            SAXParserHandler handler=new SAXParserHandler();            
            parser.parse("books.xml", handler);
            System.out.println("书的数量:"+handler.getBookList().size());
            for(Book book: handler.getBookList()){
                System.out.println(book.getId());
                System.out.println(book.getName());
                System.out.println(book.getAuthor());
                System.out.println(book.getPrice());
                System.out.println(book.getYear());
                System.out.println("-------------");
            }
        } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();            
        } catch (ParserConfigurationException | SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

输出:
SAX解析开始
开始遍历第1本书
book元素的第1个属性名:id
book元素的第1个属性值:1
节点名是:name 节点值是:冰与火之歌
节点名是:author 节点值是:乔治马丁
节点名是:year 节点值是:2014
节点名是:price 节点值是:99
遍历结束
结束遍历第1本书

开始遍历第2本书
book元素的第1个属性名:id
book元素的第1个属性值:2
节点名是:name 节点值是:秦腔
节点名是:author 节点值是:贾平凹
节点名是:price 节点值是:90
遍历结束
结束遍历第2本书

SAX解析结束
书的数量:2
1
冰与火之歌
乔治马丁
99
2014

2
秦腔
贾平凹
90
null

JDOM解析
包文件夹右键,Build Path,Add External Archices 导入JDOM jar包,但只是引用了路径,无法迁移到其他设备。
解决办法:在项目文件夹下新建一个文件夹,将jar包放进新建的文件夹之后再重新导入。右键jar包, Build Path》》》Add Path

package test;

import java.util.List;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

public class JDOMTest {

    public static void main(String[] args) {
        //JDOM解析XML文件
        //创建一个SAXBuilder对象
        SAXBuilder saxbuilder=new SAXBuilder();

        InputStream in;
        try {
            //创建一个输入流,将xml文件加载到流中
            in = new FileInputStream("src/res/books.xml");

            //通过saxbuilder的build方法将输入流加载到saxbuilder中
            Document document= saxbuilder.build(in);

            //通过document对象获取xml文件的根节点
            Element rootElement= document.getRootElement(); 

            //获取根节点下的子节点的集合
            List<Element> bookList=rootElement.getChildren();

            //使用foreach循环解析

            for (Element book : bookList) {
                System.out.println("开始解析第"+(bookList.indexOf(book)+1)
                        +"本书============");

                //解析book的属性
                List<Attribute> attrList=book.getAttributes();

//              //知道节点属性名
//              book.getAttribute("id");


                //针对不清楚book节点下属性名和数量的情况
                //遍历attrList
                for (Attribute attr : attrList) {
                    //获取属性名和属性值
                    String attrName=attr.getName();
                    String attrValue=attr.getValue();
                    System.out.println("属性名:"+attrName+"\t属性值:"+attrValue);
                }

                //对book节点的子节点的节点名和节点值进行遍历
                List<Element> bookChilds= book.getChildren();
                for (Element child : bookChilds) {
                    System.out.println("节点名:"+child.getName()+"\t节点值:"+child.getValue());
                }

                System.out.println("结束解析第"+(bookList.indexOf(book)+1)
                        +"本书============");
            }

        } catch (FileNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (JDOMException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

输出:
开始解析第1本书============
属性名:id 属性值:1
节点名:name 节点值:冰与火之歌
节点名:author 节点值:乔治马丁
节点名:year 节点值:2014
节点名:price 节点值:99
结束解析第1本书============
开始解析第2本书============
属性名:id 属性值:2
节点名:name 节点值:秦腔
节点名:author 节点值:贾平凹
节点名:price 节点值:90
结束解析第2本书============

如果解析出来中文出现乱码情况,修改XML文件第一行的encoding属性。如果修改无效,再继续在java代码中进行修改操作。创建InputStreamReader对象并直接制定字符编码:

InputStreamReader ins=new InputStreamReader(in,"UTF-8");

加入存储Book对象的操作:

package test;

import java.util.ArrayList;
import java.util.List;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

import test3.Book;

public class JDOMTest {
    private static ArrayList<Book> booksList=new ArrayList<Book>();
    public static void main(String[] args) {
        //JDOM解析XML文件
        //创建一个SAXBuilder对象
        SAXBuilder saxbuilder=new SAXBuilder();

        InputStream in;
        try {
            //创建一个输入流,将xml文件加载到流中
            in = new FileInputStream("src/res/books.xml");
//          InputStreamReader ins=new InputStreamReader(in,"UTF-8");
            //通过saxbuilder的build方法将输入流加载到saxbuilder中
            Document document= saxbuilder.build(in);

            //通过document对象获取xml文件的根节点
            Element rootElement= document.getRootElement(); 

            //获取根节点下的子节点的集合
            List<Element> bookList=rootElement.getChildren();

            //使用foreach循环解析

            for (Element book : bookList) {
                Book bookEntity=new Book();
                System.out.println("开始解析第"+(bookList.indexOf(book)+1)
                        +"本书============");

                //解析book的属性
                List<Attribute> attrList=book.getAttributes();

//              //知道节点属性名
//              book.getAttribute("id");


                //针对不清楚book节点下属性名和数量的情况
                //遍历attrList
                for (Attribute attr : attrList) {
                    //获取属性名和属性值
                    String attrName=attr.getName();
                    String attrValue=attr.getValue();
                    System.out.println("属性名:"+attrName+"\t属性值:"+attrValue);
                    //存储book节点
                    if(attrName.equals("id")){
                        bookEntity.setId(attrValue);
                    }
                }

                //对book节点的子节点的节点名和节点值进行遍历
                List<Element> bookChilds= book.getChildren();
                for (Element child : bookChilds) {
                    System.out.println("节点名:"+child.getName()+"\t节点值:"+child.getValue());

                    //存储子节点名
                    if(child.getName().equals("name")){
                        bookEntity.setName(child.getValue());
                    }else if(child.getName().equals("author")){
                        bookEntity.setAuthor(child.getValue());
                    }else if(child.getName().equals("year")){
                        bookEntity.setYear(child.getValue());
                    }else if(child.getName().equals("price")){
                        bookEntity.setPrice(child.getValue());
                    }
                }

                System.out.println("结束解析第"+(bookList.indexOf(book)+1)
                        +"本书============");
                //添加booksList集合对象
                booksList.add(bookEntity);
                bookEntity=null;
                System.out.println(booksList.size());
                System.out.println(booksList.get(0).getId());
                System.out.println(booksList.get(0).getName());
            }

        } catch (FileNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (JDOMException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

输出:
开始解析第1本书============
属性名:id 属性值:1
节点名:name 节点值:冰与火之歌
节点名:author 节点值:乔治马丁
节点名:year 节点值:2014
节点名:price 节点值:99
结束解析第1本书============
1
1
冰与火之歌
开始解析第2本书============
属性名:id 属性值:2
节点名:name 节点值:秦腔
节点名:author 节点值:贾平凹
节点名:price 节点值:90
结束解析第2本书============
2
1
冰与火之歌

DOM4J解析:
先导入DOM4J jar包

package Dom4jTest;

import java.io.File;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class DOM4JTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //创建SAXReader对象
        SAXReader reader=new SAXReader();
        //通过reader对象read 方法加载book.xml
        try {
            Document document=reader.read(new File("src/res/books.xml"));
            //通过document对象获取根节点bookstore
            Element bookStore=document.getRootElement();
            //通过element对象的elementIterator方法获取迭代器
            Iterator it=bookStore.elementIterator();
            //遍历迭代器,获取根节点中的信息
            while(it.hasNext()){
                System.out.println("开始遍历一本书");
                Element book=(Element) it.next();
                //获取book的属性名和属性值
                List<Attribute> bookAttrs=book.attributes();
                for (Attribute attr : bookAttrs) {
                    System.out.println("属性名:"+attr.getName()
                    +"\t属性值:"+attr.getValue());
                }

                Iterator itt=book.elementIterator();
                while(itt.hasNext()){
                    Element bookChild=(Element) itt.next();
                    System.out.println("节点名:"+bookChild.getName()+
                            "\t节点值:"+bookChild.getStringValue());
                }

                System.out.println("结束遍历一本书"+"\n");
            }
        } catch (DocumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

输出:
开始遍历一本书
属性名:id 属性值:1
节点名:name 节点值:冰与火之歌
节点名:author 节点值:乔治马丁
节点名:year 节点值:2014
节点名:price 节点值:99
结束遍历一本书

开始遍历一本书
属性名:id 属性值:2
节点名:name 节点值:秦腔
节点名:author 节点值:贾平凹
节点名:price 节点值:90
结束遍历一本书

四种解析方式对比:
基础:
DOM(跨平台)、一次性加载全部XML。
优点:形成了树结构,直观显示,代码编写简单;解析过程中树结构保留在内存中,便于修改。
缺点:XML文件较大时,太耗内存,影响解析操作并造成内存溢出。

SAX(基于事件驱动的解析方式)逐行读取解析
优点:占内存小,适用于只处理XML中的数据。
缺点:不易编码,很难同时访问同一个XML中的多出不同数据。

扩展(仅在JAVA平台使用):JDOM仅使用具体类而不是接口,API大量使用了Cillections类。
DOM4J、是JDOM的一种只能分支。合并了很多超出基本XML文档表示的功能;使用接口和抽象基本类;具有灵活性好,性能特异,功能强大和极端易用的特点。开源软件。

阅读更多
文章标签: xml java
个人分类: JAVA Web
想对作者说点什么? 我来说一句

java解析XML文件

2010年08月10日 6KB 下载

java解析XML文件DOMO

2014年10月15日 285KB 下载

Java解析XML文件

2013年03月09日 38KB 下载

XML解析器,用于解析XML文件

2011年11月06日 250KB 下载

一个Java 解析XML的例子

2009年07月28日 579KB 下载

没有更多推荐了,返回首页

不良信息举报

JAVA解析XML文件

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭