Java之xml文件解析

目录

0、前言

1、 什么是XML?

2、 XML语法

2.1、XML文档声明

2.2、元素element

2.3、属性

2.4、注释

2.5、转义字符

2.6、CDATA区

2.7、命名空间(属于语法部分)

3、什么是DTD约束

4、schema约束

5、dom4j解析

5.1、解析方式和解析器

5.2、常见的解析开发包

6、代码演练

6.1、DOM方式读取

6.2、SAX方式读取

6.3、JDOM读取

6.4、DOMJ4读取


0、前言

       为了灵活实现不同路径执行不同的资源,我们需要用XML进行配置,为了限定XML内容,我们需要用XML约束(DTD或schema),为了获得XML的内容,我们可以利用已有的开发包灵活的编写特定的java程序去解析。

1、 什么是XML?

       XML英文名称为Extensible Markup Language,意思是可扩展的标记语言。XML语法上和HTML比较相似,但HTML中的元素是固定的,而XML的标签是可以由用户自定义的

因为W3C后面出的新版本都不兼容旧版本,所以目前学习使用的都还是XML1.0版本

2、 XML语法

2.1、XML文档声明

1.文档声明必须为<?xml开头,以?>结束;

2.文档声明必须从文档的0行0列位置开始:

3.文档声明只有属性:

       a) versioin:指定XML文档版本必选属性,因为我们不会选择1.1,选择1.0;

       b) encoding:指定当前文档的编码可选属性,默认值是。utf-8:

2.2、元素element

1.元素是XML文档中最重要的组成部分,

2.普通元素的结构开始标签、元素体、结束标签组成。例如:<hello>大家好</hello>

3.元素体:元素体可以是元素,也可以是文本,例如:<b><a>你好</a ></b>

4.空元素:空元素只有开始标签,而没有结束标签,但元素必须自己闭介,例如:<c/>

5.元素命名:

a) 区分大小写

b)不能使用空格,不能使用冒号:

c)不建议以XML,  xml,  Xml开头

6.格式化良好的XML文档,必须只有一个根元素

2.3、属性

1.属性是元素的一部分,它必须出现在元素的开始标签中

2.属性的定义格式:属性名=属性值,其中属性值必须使用单引或双引

3.一个元素可以有多个属性,但一个元素中不能出现同名属性,属性以空格隔开

4.属性名不能使用空格、冒号等特殊字符,且必须以字母开头

2.4、注释

XML的注释与HTML相同,即以“<!--”开始,以“-->”结束。注释内容会被XML解析器忽略!

2.5、转义字符

XML中的转义字符与HTML一样。

因为很多符号己经被XML文档结构所使用,所以在元素体或属性值中想使用这些符号就必须使用转义字符,例如:"<"、”>”、” ’ ”、” ” ”、”&”。注意:分号 “;” 不能丢

 

2.6、CDATA区

当大量的转义字符出现在xml文档中时,会使xml文档的可读性大幅度降低。这时如果使用CDATA段就会好一些。

在CDATA段中出现的“<”、“>’,、“””、“‘”、“&”,都无需使用转义字符。这可以提高xml文档的可读性

     注意:  在CDATA段中不能包含“]]>”,即CDATA段的结束定界符。

2.7、命名空间(属于语法部分)

 名称空间就是用来处理元素和属性的名称冲突问题

 声明命名空间:

3、什么是DTD约束

 DTD (Document Type Definition ),文档类型定义用来约束XML文档规定XML文档中元素名称,子元素的名称及顺序,元素的属性等。

通过提供的DTD"web-app_2_3.dtd "编写XML

(重点)实现步骤:

  步骤1:创建web.xml文档,并将“web-app_ 2_ 3.dtd"拷贝相同目录下。

步骤2:从DTD文档开始处,拷贝需要的“文档声明”

4、schema约束

 4.1、什么是schema约束

 1) Schema是新的XML文档约束:

 2)Schema要比DTD强大很多,是DTD替代者;

 3)Schema本身也是XML文档,但Schema文档的扩展名为xsd,而不是xml .

 4)Schema功能更强大,数据类型更完善

 5)Schema支持名称空间

5、dom4j解析

 当将数据存储在XML后,我们就希望通过程序获得XML的内容。如果用java的方法会很繁琐,但是用解析方法就很简便了。

5.1、解析方式和解析器

开发中比较常见的解析方式有三种,如下:

1、DOM:要求解析器把整个XML文档装载到内存,并解析成一个Document对象

a)  优点:元素与元素之间保留结构关系,故可以进行增删改查操作

b)  缺点:XML文档过大,可能出现内存溢出显现。

2、SAX:是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。并以事件驱动的方式进行具体解析,每执行一行,都将触发对应的事件。(了解即可)

a)  优点:处理速度快,可以处理大文件

b)  缺点:只能读,逐行后将释放资源。

3.  PULL Android内置的XML解析方式,类似SAX。(了解即可)

    解析器:就是根据不同的解析方式提供的具体实现。有的解析器操作过于繁琐,为了方便开发人员,有提供易于操作的解析开发包。

 

5.2、常见的解析开发包

   1)JAXP: sun公司提供支持DOM和SAX开发包

   2)JDom:dom4j兄弟

  3)jsoup:一种处理HTML特定解析开发包

  4)dom4j:比较常用的解析开发包,hibernate底层采用。我们只用这种

6、代码演练

1.DOM方式解析XML
      Dom解析是将xml文件全部载入到内存,组装成一颗dom树,然后通过节点以及节点之间的关系来解析xml文件,与平台无关,java提供的一种基础的解析XML文件的API,理解较简单,但是由于整个文档都需要载入内存,不适用于文档较大时。

2.SAX方式解析XML
       基于事件驱动,逐条解析,适用于只处理xml数据,不易编码,而且很难同时访问同一个文档中的多处不同数据

3.JDOM方式解析XML
      简化与XML的交互并且比使用DOM实现更快,仅使用具体类而不使用接口因此简化了API,并且易于使用

4.DOM4j方式解析XML
      JDOM的一种智能分支,功能较强大,建议熟练使用

books.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>
        <author>安徒生</author>
        <year>2004</year>
        <price>77</price>
    </book>
    <book id="3">
        <name>think think think</name>
        <author>aaa</author>
        <year>1997</year>
        <price>100</price>
    </book>
</bookstore>

Book.java:

package xml_read;
public class Book {

    private int id;
    private String name;
    private String author;
    private int year;
    private double price;

    /**
     * @return the id
     */
    public int getId() {
        return id;
    }
    /**
     * @param id the id to set
     */
    public void setId(int id) {
        this.id = id;
    }
    /**
     * @return the name
     */
    public String getName() {
        return name;
    }
    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }
    /**
     * @return the author
     */
    public String getAuthor() {
        return author;
    }
    /**
     * @param author the author to set
     */
    public void setAuthor(String author) {
        this.author = author;
    }
    /**
     * @return the year
     */
    public int getYear() {
        return year;
    }
    /**
     * @param year the year to set
     */
    public void setYear(int year) {
        this.year = year;
    }
    /**
     * @return the price
     */
    public double getPrice() {
        return price;
    }
    /**
     * @param price the price to set
     */
    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Book [id=" + id + ", name=" + name + ", author=" + author + ", year=" + year + ", price=" + price + "]";
    }

}

6.1、DOM方式读取

package xml_read;

import java.util.ArrayList;
import java.util.List;

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.NodeList;

//import com.lune.bean.Book;

/**
 * 用DOM方式读取xml文件
 */
public class ReadxmlByDom {
    private static DocumentBuilderFactory dbFactory = null;
    private static DocumentBuilder db = null;
    private static Document document = null;
    private static List<Book> books = null;
    static{
        try {
            dbFactory = DocumentBuilderFactory.newInstance();
            db = dbFactory.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
    }

    public static List<Book> getBooks(String fileName) throws Exception{
        //将给定 URI 的内容解析为一个 XML 文档,并返回Document对象
        document = db.parse(fileName);
        //按文档顺序返回包含在文档中且具有给定标记名称的所有 Element 的 NodeList
        NodeList bookList = document.getElementsByTagName("book");
        books = new ArrayList<Book>();
        //遍历books
        for(int i=0;i<bookList.getLength();i++){
            Book book = new Book();
            //获取第i个book结点
            org.w3c.dom.Node node = bookList.item(i);
            //获取第i个book的所有属性
            NamedNodeMap namedNodeMap = node.getAttributes();
            //获取已知名为id的属性值
            String id = namedNodeMap.getNamedItem("id").getTextContent();//System.out.println(id);
            book.setId(Integer.parseInt(id));

            //获取book结点的子节点,包含了Test类型的换行
            NodeList cList = node.getChildNodes();//System.out.println(cList.getLength());9

            //将一个book里面的属性加入数组
            ArrayList<String> contents = new ArrayList<>();
            for(int j=1;j<cList.getLength();j+=2){

                org.w3c.dom.Node cNode = cList.item(j);
                String content = cNode.getFirstChild().getTextContent();
                contents.add(content);
                //System.out.println(contents);
            }

            book.setName(contents.get(0));
            book.setAuthor(contents.get(1));
            book.setYear(Integer.parseInt(contents.get(2)));
            book.setPrice(Double.parseDouble(contents.get(3)));
            books.add(book);
        }

        return books;

    }

    public static void main(String args[]){
        String fileName = "src/xml_read/books.xml";
        try {
            List<Book> list = ReadxmlByDom.getBooks(fileName);
            for(Book book :list){
                System.out.println(book);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

6.2、SAX方式读取

package xml_read;

import java.io.IOException;
import java.util.List;

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

import org.xml.sax.SAXException;
import org.xml.sax.helpers.ParserFactory;

/**
 * 用SAX方式读取xml文件
 */
public class ReadXmlBySAX {

    private static List<Book> books = null;

    private  SAXParserFactory sParserFactory = null;
    private  SAXParser parser = null;


    public List<Book> getBooks(String fileName) throws Exception{
        SAXParserFactory sParserFactory = SAXParserFactory.newInstance();
        SAXParser parser = sParserFactory.newSAXParser();

        SAXParseHandler handler = new SAXParseHandler();
        parser.parse(fileName, handler);

        return handler.getBooks();

    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            books = new ReadXmlBySAX().getBooks("src/xml_read/books.xml");
            for(Book book:books){
                System.out.println(book);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

6.3、JDOM读取

package xml_read;

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

import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;


import org.jdom2.*;

/**
 * 用JDOM方式读取xml文件
 */
public class ReadXMLByJDom {

    private List<Book> books = null;
    private Book book = null;

    public List<Book> getBooks(String fileName){
        SAXBuilder saxBuilder = new SAXBuilder();
        try {
            Document document = saxBuilder.build(new FileInputStream(fileName));
            //获取根节点bookstore
            Element rootElement = document.getRootElement();
            //获取根节点的子节点,返回子节点的数组
            List<Element> bookList = rootElement.getChildren();
            books = new ArrayList<Book>();
            for(Element bookElement : bookList){
                book = new Book();
                //获取bookElement的属性
                List<Attribute> bookAttributes = bookElement.getAttributes();
                for(Attribute attribute : bookAttributes){
                    if(attribute.getName().equals("id")){
                        String id = attribute.getValue(); //System.out.println(id);
                        book.setId(Integer.parseInt(id));
                    }
                }
                //获取bookElement的子节点
                List<Element> children = bookElement.getChildren();
                for(Element child : children){
                    if(child.getName().equals("name")){
                        String name = child.getValue();//System.out.println(name);
                        book.setName(name);
                    }else if(child.getName().equals("author")){
                        String author = child.getValue();
                        book.setAuthor(author);//System.out.println(author);
                    }else if(child.getName().equals("year")){
                        String year = child.getValue();
                        book.setYear(Integer.parseInt(year));
                    }else if(child.getName().equals("price")){
                        String price = child.getValue();
                        book.setPrice(Double.parseDouble(price));
                    }

                }

                books.add(book);
                book = null;

            }

        } catch (FileNotFoundException e) {

            e.printStackTrace();
        } catch (JDOMException e) {

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

            e.printStackTrace();
        }

        return books;

    }


    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String fileName = "src/xml_read/books.xml";
        List<Book> books= new ReadXMLByJDom().getBooks(fileName);
        for(Book book : books){
            System.out.println(book);
        }
    }

}

6.4、DOMJ4读取

package xml_read;

import java.io.File;
import java.util.ArrayList;
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;

/**
 * 用DOM4J方法读取xml文件
 */
public class ReadXMLByDom4j {

    private List<Book> bookList = null;
    private Book book = null;

    public List<Book> getBooks(File file){

        SAXReader reader = new SAXReader();
        try {
            Document document = reader.read(file);
            Element bookstore = document.getRootElement();
            Iterator storeit = bookstore.elementIterator();

            bookList = new ArrayList<Book>();
            while(storeit.hasNext()){

                book = new Book();
                Element bookElement = (Element) storeit.next();
                //遍历bookElement的属性
                List<Attribute> attributes = bookElement.attributes();
                for(Attribute attribute : attributes){
                    if(attribute.getName().equals("id")){
                        String id = attribute.getValue();//System.out.println(id);
                        book.setId(Integer.parseInt(id));
                    }
                }

                Iterator bookit = bookElement.elementIterator();
                while(bookit.hasNext()){
                    Element child = (Element) bookit.next();
                    String nodeName = child.getName();
                    if(nodeName.equals("name")){
                        //System.out.println(child.getStringValue());
                        String name = child.getStringValue();
                        book.setName(name);
                    }else if(nodeName.equals("author")){
                        String author = child.getStringValue();
                        book.setAuthor(author);
                    }else if(nodeName.equals("year")){
                        String year = child.getStringValue();
                        book.setYear(Integer.parseInt(year));
                    }else if(nodeName.equals("price")){
                        String price = child.getStringValue();
                        book.setPrice(Double.parseDouble(price));
                    }
                }
                bookList.add(book);
                book = null;

            }
        } catch (DocumentException e) {

            e.printStackTrace();
        }


        return bookList;

    }


    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        File file = new File("src/xml_read/books.xml");
        List<Book> bookList = new ReadXMLByDom4j().getBooks(file);
        for(Book book : bookList){
            System.out.println(book);
        }
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值