Dom4J & XPath & SAX 解析 XML 文件

1.什么是XML语言

可扩展标记语言,标准通用标记语言的子集,简称XML。是一种用于标记电子文件使其具有结构性的标记语言。 [1]

在电子计算机中,标记指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种的信息比如文章等。它可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 它非常适合万维网传输,提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。是Internet环境中跨平台的、依赖于内容的技术,也是当今处理分布式结构信息的有效工具。早在1998年,W3C就发布了XML1.0规范,使用它来简化Internet的文档信息传输。

上述内容来自百度百科
2.XML的作用,用来存储数据
3.解析XML的方法:DOM DOM4J SAX

Dom4J解析XML文件
导入Dom4J.jar包 此处我使用Maven项目,此处导入依赖如下
    
        dom4j
        dom4j
        1.6.1
    
准备 XML 数据



    
        哈希
        1525264652
        江苏科技大学
        男,喜欢数据研发
    

    
        Teble
        15244664652
        苏州科技大学
        男,喜欢女
    

    
        Tom
        1525264652
        江苏科技大学
        女,喜欢男
    

    
        siri
        1525264652
        家里蹲大学
        女,假的人工智能
    

测试代码

package cn.icanci.dom4j;

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

import java.util.Iterator;

/**
 * @Author: icanci
 * @ProjectName: dom4janno
 * @PackageName: cn.icanci.dom4j
 * @Date: Created in 2020/2/22 17:01
 * @ClassAction: dom4j 解析
 */
public class Dom4jTest1 {
    public static void main(String[] args) {
        try {
            //1.创建解析器
            SAXReader saxReader = new SAXReader();
            //2.通过解析器的read方法将配置文件读取到内存中,生成一个Document[org.dom4j]对象数
            //3.从文件根目录找到文件
            Document document = saxReader.read(Dom4jTest1.class.getResource("/").toString() + "students.xml");
            //4.获取根节点
            Element rootElement = document.getRootElement();
            //5.获取根节点
            for (Iterator rootIterator = rootElement.elementIterator();rootIterator.hasNext();){
                //获取第二级节点
                Element studentElement = rootIterator.next();
                //获取第三级节点的内容
                for (Iterator innerIter = studentElement.elementIterator();innerIter.hasNext();){
                    Element innerElement = innerIter.next();
                    String innerValue = innerElement.getStringValue();
                    System.out.println(innerValue);
                }
                System.out.println("----------------------------------");
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
}
打印结果
哈希
1525264652
江苏科技大学
男,喜欢数据研发
----------------------------------
Teble
15244664652
苏州科技大学
男,喜欢女
----------------------------------
Tom
1525264652
江苏科技大学
女,喜欢男
----------------------------------
siri
1525264652
家里蹲大学
女,假的人工智能
----------------------------------
SAX解析XML文件 优点 无需将整个文档加载到内存中,所以内存消耗小,适合解析特别大的xml文件
SAX解析四步曲
1.创建解析工厂 通过newInstance()方法获取
SAXParserFactory sax = SAXParserFactory.newInstance();
2.创建解析器
SAXParser saxParser = sax.newSAXParser();
3.通过解析器 parser 方法
saxParser.parse(Dom4jTest1.class.getResource("/").toString() + "students.xml", new MyDefaultHander());

完整代码

package cn.icanci.dom4j;

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

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.sql.SQLOutput;

/**
 * @Author: icanci
 * @ProjectName: dom4janno
 * @PackageName: cn.icanci.dom4j
 * @Date: Created in 2020/2/22 17:28
 * @ClassAction: SAX 解析数据
 */
public class Dom4jTest2 {
    public static void main(String[] args) {
        try {
            //1.创建解析器工厂
            SAXParserFactory sax = SAXParserFactory.newInstance();
            //2.创建解析器
            SAXParser saxParser = sax.newSAXParser();
            //3.通过解析器 parser 方法
            saxParser.parse(Dom4jTest1.class.getResource("/").toString() + "students.xml", new MyDefaultHander());
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class MyDefaultHander extends DefaultHandler {
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        System.out.print("<" + qName + ">");
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        System.out.print(new String(ch, start, length));
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        System.out.print("");
    }
}
数据打印 拿到数据到内存之后,就可以解析了

    
        哈希
        1525264652
        江苏科技大学
        男,喜欢数据研发
    

    
        Teble
        15244664652
        苏州科技大学
        男,喜欢女
    

    
        Tom
        1525264652
        江苏科技大学
        女,喜欢男
    

    
        siri
        1525264652
        家里蹲大学
        女,假的人工智能
    

使用Dom4J的xPath解析XML文件
1.XPath语法

参考文档 https://www.w3school.com.cn/xpath/index.asp

2.xpath使用路径表达式选择XML文档中的节点或者节点集.节点是通过路径(path)或者(steps)来选取的
2.xpath的语法选取节点 请参考上面文档连接内容

Dom4J+XPath解析 XML 文档
1.首先导入依赖
        
            jaxen
            jaxen
            1.1.1
        
2.准备XML文件

sys-info.xml



    
        com.mysql.jdbc.Driver
        jdbc:mysql:///test
        root
        ok
    

3.编写代码
package cn.icanci.dom4j;

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

import javax.xml.parsers.SAXParser;
import java.lang.annotation.ElementType;

/**
 * @Author: icanci
 * @ProjectName: dom4janno
 * @PackageName: cn.icanci.dom4j
 * @Date: Created in 2020/2/22 18:09
 * @ClassAction: Dom4J + XPath
 */
public class Dom4jTest3 {
    public static void main(String[] args) {
        try {
            //1.创建解析器
            SAXReader reader = new SAXReader();
            //2.通过解析器的 read 方法把配置文件读取到内存中,生成一个Document[org.dom4j]对象书
            Document document = reader.read(Dom4jTest3.class.getResource("/") + "sys-info.xml");
            //driver-name 怎么拿到 driver-name 节点路径 config -> database-info -> driver-name
            //driver-name 节点的xpath路径 /config/database-info/driver-name
            Element driverNameElt = (Element) document.selectSingleNode("/config/database-info/driver-name");
            //获取driverNameElt节点对象的文本内容
            String driverName = driverNameElt.getStringValue();
            System.out.println(driverName);

            //获取url节点的xpath路径 /config/database-info/url
            //获取url节点的xpath路径 /config//url
            Element urlElement = (Element) document.selectSingleNode("/config//url");
            String url = urlElement.getStringValue();
            System.out.println(url);

            //获取user节点的xpath路径 /config/database-info/user
            //获取user节点的xpath路径 /config//user
            //获取user节点的xpath路径 //user
            Element userElement = (Element) document.selectSingleNode("//user");
            String user = userElement.getStringValue();
            System.out.println(user);

            //获取password节点的xpath路径 /config/database-info/password
            //获取password节点的xpath路径 /config//password
            //获取password节点的xpath路径 //password
            Element passwordElement = (Element) document.selectSingleNode("//password");
            String password = passwordElement.getStringValue();
            System.out.println(password);
        } catch (DocumentException e) {
            e.printStackTrace();
        }

    }
}
测试结果
com.mysql.jdbc.Driver
jdbc:mysql:///test
root
ok
解析带有属性的XML节点文件 server.xml


    
        
        
        
    

测试
package cn.icanci.dom4j;

import org.dom4j.*;
import org.dom4j.io.SAXReader;

import java.time.Year;

/**
 * @Author: icanci
 * @ProjectName: dom4janno
 * @PackageName: cn.icanci.dom4j
 * @Date: Created in 2020/2/22 18:41
 * @ClassAction:
 */
public class Dom4jTest4 {

    public static void main(String[] args) {
        try {
            //1.创建解析器
            SAXReader reader = new SAXReader();
            //2.通过解析器的read获取文件加载到内存 生成 document 对象树
            Document document = reader.read(Dom4jTest4.class.getResource("/") + "server.xml");
            //3.获取connector节点元素对象的路径 server -> service -> connector
            //3.获取connector节点元素对象的xpath路径 /server/service/connector
            //3.获取connector节点元素对象的xpath路径 server/service/connector
            //3.获取connector节点元素对象的xpath路径 server//connector
            //3.获取connector节点元素对象的xpath路径 //connector
            Element connEle = (Element) document.selectSingleNode("/server/service/connector");
            Attribute portAttr = connEle.attribute("port");
            String portAttrValue = portAttr.getValue();
            System.out.println(portAttrValue);

            System.out.println("-------------------");

            String port = connEle.attributeValue("port");
            System.out.println(port);
            //此种方式只能获取1个
            String driverUrl = connEle.attributeValue("driverUrl");
            System.out.println(driverUrl);

            String url = connEle.attributeValue("url");
            System.out.println(url);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
}
测试结果 只能获取第一个接节点的属性
8080
-------------------
8080
null
null
解决方案
package cn.icanci.dom4j;

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

import java.util.List;

/**
 * @Author: icanci
 * @ProjectName: dom4janno
 * @PackageName: cn.icanci.dom4j
 * @Date: Created in 2020/2/22 18:41
 * @ClassAction:
 */
public class Dom4jTest6 {

    public static void main(String[] args) {
        try {
            //1.创建解析器
            SAXReader reader = new SAXReader();
            //2.通过解析器的read获取文件加载到内存 生成 document 对象树
            Document document = reader.read(Dom4jTest6.class.getResource("/") + "server.xml");
            //3.获取connector节点元素对象的路径 server -> service -> connector
            //3.获取connector节点元素对象的xpath路径 /server/service/connector
            //3.获取connector节点元素对象的xpath路径 server/service/connector
            //3.获取connector节点元素对象的xpath路径 server//connector
            //3.获取connector节点元素对象的xpath路径 //connector
            Element connEle = (Element) document.selectSingleNode("/server/service");
            List elements = connEle.elements();
            for (int i =0 ; i 
打印结果
org.dom4j.tree.DefaultElement@2aafb23c [Element: ]
org.dom4j.tree.DefaultElement@3ab39c39 [Element: ]
org.dom4j.tree.DefaultElement@7907ec20 [Element: ]
8080
127.0.0.1
127.33.22.1
XPath解析XML文件 books.xml




    
        Everyday Italian
        Giada De Laurentiis
        2005
        30.00
    

    
        Harry Potter
        J K. Rowling
        2005
        29.99
    

    
        XQuery Kick Start
        James McGovern
        Per Bothner
        Kurt Cagle
        James Linn
        Vaidyanathan Nagarajan
        2003
        49.99
    

    
        Learning XML
        Erik T. Ray
        2003
        39.95
    

测试代码
package cn.icanci.dom4j;

import org.apache.xpath.res.XPATHErrorResources;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.*;
import java.io.IOException;

/**
 * @Author: icanci
 * @ProjectName: dom4janno
 * @PackageName: cn.icanci.dom4j
 * @Date: Created in 2020/2/22 19:01
 * @ClassAction:
 */
public class Dom4jTest5 {
    public static void main(String[] args) {
        try {
            //1.创建解析工厂
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            //2.创建解析器
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            //3.通过解析器来读取配置文件 生成一个Document[org.w3c.dom]对象树
            Document document = documentBuilder.parse(Dom4jTest5.class.getResource("/") + "books.xml");
            //4.创建XPath对象
            XPath xPath = XPathFactory.newInstance().newXPath();
            //获取 books.xml bookstore 属性category值为web下的第二个title节点的文本内容
            //bookstore -> category -> WEB - >第二个 title
            //bookstore -> book[@category='WEB'] -> title
            //xpath 路径 /bookstore/book[@category='WEB'][2]/title/text()
            String titleValue = (String) xPath.evaluate("/bookstore/book[@category='WEB'][2]/title/text()", document, XPathConstants.STRING);
            System.out.println(titleValue);


            System.out.println("-------------------------");

            //获取 books.xml bookstore 属性category值为web下的第二个title节点属性为en的节点内容
            //bookstore -> category -> WEB - >第二个 title
            // bookstore -> book[@category='WEB'] -> title
            // bookstore/book[@category='WEB']/title[@lang='en']/text()
            String titleValue2 = (String) xPath.evaluate("bookstore/book[@category='WEB']/title[@lang='en']/text()", document, XPathConstants.STRING);
            System.out.println(titleValue2);

            System.out.println("-------------------------");
            //获取 books.xml bookstore 属性category值为 COOKING 下的title节点的lang的值
            //bookstore/book[@category='COOKING']/title/@lang
            String evaluate = (String) xPath.evaluate("bookstore/book[@category='COOKING']/title/@lang", document, XPathConstants.STRING);
            System.out.println(evaluate);

            System.out.println("-------------------------");
            //获取 books.xml bookstore 所有 book 结点的集合
            // bookstore/book
            NodeList list = (NodeList)xPath.evaluate("bookstore/book", document, XPathConstants.NODESET);
            //开始遍历list
            for (int i = 0; i < list.getLength(); i++) {
                Element bookEle= (Element)list.item(i);
                String title = (String)xPath.evaluate("title", bookEle, XPathConstants.STRING);
                System.out.println(title);
                String author = (String)xPath.evaluate("author", bookEle, XPathConstants.STRING);
                System.out.println(author);
                String year = (String)xPath.evaluate("year", bookEle, XPathConstants.STRING);
                System.out.println(year);
                String price = (String)xPath.evaluate("price", bookEle, XPathConstants.STRING);
                System.out.println(price);
                System.out.println();
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }
    }
}
打印
Learning XML
-------------------------
XQuery Kick Start
-------------------------
en
-------------------------
Everyday Italian
Giada De Laurentiis
2005
30.00

Harry Potter
J K. Rowling
2005
29.99

XQuery Kick Start
James McGovern
2003
49.99

Learning XML
Erik T. Ray
2003
39.95

你可能感兴趣的:(Dom4J & XPath & SAX 解析 XML 文件)