XML文档详解

目录

XML文档

一、XML文件

二、Dom4J解析XML文件

三、Sax解析XML文件

四、使用Dom4j的XPath解析XML文件

4.1XPath语法

[4.2 获取sys-config.xml文件的配置信息](#4.2 获取sys-config.xml文件的配置信息)

[4.3 获取server.xml文件的配置信息](#4.3 获取server.xml文件的配置信息)

[4.4 获取bookstore.xml文件的配置信息](#4.4 获取bookstore.xml文件的配置信息)


XML文档

一、XML文件

1.1 学习重点

由于在现代开发过程中,不需要开发人员手动解析XML文档,因此本次课程主要内容了解XML文档基本学习,以及XML约束文档内容。

1.2 XML编程语言

  • 名称:可扩展标记编程语言,就是开发者在符合XML命名规则的基础之上,可以根据自己的需求定义自己的标签。

  • XML文档作用:

    • 主要用来存储数据

    • 最初XML文档作为网页来使用(现在是HTML)

    • 在Java使用XML文档来代替properties作为配置文件

  • 解析XML文件的方法:DOM、DOM4J、SAX

1.3 XML语法

  • HTML是从XML演化出来的一种编程语言,XML与HTML是父子关系。

  • HTML绝大多数语法都来自XML。

  • 一个XML文档必须以一个根目录标签开始,其它标签必须作为根目录标签的直接子标签或者间接子标签出现。

  • HTML标签对于英文字母大小是忽略不计,但是XML标签必须区分英文字母大小写。

  • HTML标签中属性内容可以通过一对" "包含,也可以不用。XML标签属性内容必须包含在一对" "或者' '。

1.4 XML文档读取方式

  • SAX读取方式:根据开发人员需要,一次将若干个满足条件标签加载到内存中。

    • 优点:可以节省内存。

    • 缺点:如果读取大量标签信息时,运行效率相对较低。

  • DOM读取方式:一次性将XML文档所有的内容加载到内存中。

    • 优点:如果读取大量标签信息时,此时由于是在内存中进行定位,所有运行速度较快。

    • 缺点:浪费内存。

  • 实际开发过程中,一般都采用DOM方式来读取。

二、Dom4J解析XML文件

2.1导入Dom4J.jar包

2.2 Dom4J常用的对象

  • SAXReader:读取XML文件到Document树结构文件对象。

  • Document:是一个XML文档对象树,类比HTML文档对象。

  • Element:元素节点。通过Document对象可以查找单个元素。

2.3 Dom4J解析步骤

package com.hhb.xml;
​
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
​
import java.util.Iterator;
​
public class Dom4jTest {
    public static void main(String[] args) throws Exception {
​
        //创建解析器
        SAXReader reader = new SAXReader();
        //通过解析器的read方法将配置文件读取到内存当中,生成一个Document对象树
        Document document = null;
        document = reader.read("C:\\Users\\Administrator\\IdeaProjects\\xml1\\conf\\students.xml");
        //获取根节点
        Element root = document.getRootElement();
        //开始遍历根节点
        //遍历 root 根节点下的 student 子节点
        for (Iterator iter = root.elementIterator(); iter.hasNext(); ) {
            //获取 student 节点对象
            Element stuElement = (Element) iter.next();
            //遍历 stuElement 节点下的所有子节点:name,colleage,telephone,note
            for (Iterator innerIter = stuElement.elementIterator(); innerIter.hasNext(); ) {
                //获取 student 节点下的子节点对象
                Element innerElement = (Element) innerIter.next();
                //通过 innerElement 的 getName()获取节点名称,getStringValue()获取节点值
                String innerValue = innerElement.getStringValue();
                System.out.println(innerValue);
            }
            System.out.println("--------------------------------");
        }
    }
}
复制代码

三、Sax解析XML文件

3.1 SAX方式:事件驱动,边读边写

  • 优点:无需将整个文档加载到内存中,所有内存消耗较少,适合解析特别大的XML文件。

SAX解析步骤

package com.hhb.xml;
​
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;
​
public class SAXTest {
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        //创建解析工厂:通过newInstance()方法获取
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        //创建解析器
        SAXParser saxParser = saxParserFactory.newSAXParser();
        //执行parser方法,传入两个参数:XML文件路径、事件处理器
        saxParser.parse("C:\\Users\\Administrator\\IdeaProjects\\xml1\\conf\\persons.xml", new MyDefaultHander1());
    }
}
//创建一个类,继承DefaultHandler类,重写三个方法
//startElement 获取开始标签,重要的两个参数说明
//qName 把标签名称返回
//attributes 返回标签中的属性对象
//character 获取标签文本内容
//endElement 获取结束标签
class MyDefaultHander1 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("</" + qName + ">");
    }
}
复制代码

四、使用Dom4j的XPath解析XML文件

4.1XPath语法

  • XPath使用路径表达式来选取XML文档中的节点或节点集。节点是通过沿着路径(path)或者(steps)来的。

  • XML实例文档

    <?xml version="1.0" encoding="ISO-8859-1"?>
    ​
    <bookstore>
    ​
    <book>
      <title lang="eng">Harry Potter</title>
      <price>29.99</price>
    </book>
    ​
    <book>
      <title lang="eng">Learning XML</title>
      <price>39.95</price>
    </book>
    ​
    </bookstore>
    
  • 路径表达式

    表达式 描述
    nodename 选取此节点的所有子节点
    / 从根节点选取
    // 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置
    . 选取当前节点
    .. 选取当前节点的父节点
    @ 选取属性
  • 实例

    路径表达式 结果
    bookstore 选取bookstore元素的所有子节点
    /bookstore 选取根元素bookstore(假如路径起始于正斜杠/,则此路径始终代表到某元素的绝对路径)
    bookstore/book 选取属于bookstore的子元素的所有book元素
    //book 选取所有book子元素,而不管它们在文档中的位置
    bookstore//book 选取属于bookstore元素的后代的所有book元素,而不管它们位于bookstore之下的什么位置
    //@lang 选取名为lang的所有属性
    路径表达式 结果
    /bookstore/book[1] 选取属于bookstore子元素的第一个book元素
    /bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素。
    /bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素。
    /bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
    //title[@lang] 选取所有拥有名为lang的属性的title元素
    //title[@lang='eng'] 选取所有title元素,且这些元素拥有值为eng的lang属性
    /bookstore/book[price>35.00] 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
    /bookstore/book[price>35.00]/title 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。

4.2 获取sys-config.xml文件的配置信息

准备工作

  • 导入dom4j-1.6.1.jar 和 jaxen-1.1-beta-7.jar

  • sys-config.xml文档

    复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <config>
        <database-info>
            <driver-name>com.mysql.jdbc.Driver</driver-name>
            <url>jdbc:mysql://192.168.1.151:3366/bjpowernode</url>
            <user>root</user>
            <password>123</password>
        </database-info>
    </config>

解析步骤

package com.hhb.xml;
​
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
​
public class SysConfigTest {
    public static void main(String[] args) throws Exception{
        //创建解析器
        SAXReader reader = new SAXReader();
        //通过解析器的read方法将配置文件读取到内存中,生成一个Document对象树
        Document document = reader.read("C:\\Users\\Administrator\\IdeaProjects\\xml1\\conf\\sys-config.xml");
        //获取driver-name节点元素对象的文本内容
        Element driverNameElt = (Element) document.selectSingleNode("/config/database-info/driver-name");
        String driverName = driverNameElt.getStringValue();
        System.out.println(driverName);
        //获取url节点元素对象的文本内容
        Element urlElt = (Element) document.selectSingleNode("config//url");
        String url = urlElt.getStringValue();
        System.out.println(url);
        //获取user节点
        Element userElt = (Element) document.selectSingleNode("//user");
        String user = userElt.getText();
        System.out.println(user);
        //获取password节点
        Element passwordElt = (Element) document.selectSingleNode("//password");
        String password = passwordElt.getTextTrim();
        System.out.println(password);
    }
}

4.3 获取server.xml文件的配置信息

package com.hhb.xml;
​
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
​
public class ServerTest {
    public static void main(String[] args) throws Exception{
        //创建解析器
        SAXReader reader = new SAXReader();
        //通过解析器的read方法将配置文件读到内存中,生成一个Document对象树
        Document document = reader.read("C:\\Users\\Administrator\\IdeaProjects\\xml1\\conf\\server.xml");
        //获取connector节点元素对象的路径
        Element connectorElt = (Element) document.selectSingleNode("//connector");
        //获取connectorElt节点元素对象的port属性对象
       // Attribute portAttr = connectorElt.attribute("port");
        //获取portAttr属性对象的值
        //String port = portAttr.getStringValue();
        String port = connectorElt.attributeValue("port");
        System.out.println(port);
    }
}
​

4.4 获取bookstore.xml文件的配置信息

package com.hhb.xml;
​
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
​
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
​
public class BookTest {
    public static void main(String[] args) throws Exception {
        //创建解析工厂
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        //创建解析器
        DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
        //创建解析器读取配置文件,生成一个Document对象树
        Document document = builder.parse("C:\\Users\\Administrator\\IdeaProjects\\xml1\\conf\\bookstore.xml");
        //创建XPath对象
        XPath xPath = XPathFactory.newInstance().newXPath();
​
        //获取bookstore节点下book属性category值为web的title属性为en的节点内容
        //bookstore -> book[@category='web'] -> title[@lang='en']
        String titleLangXpath = "/bookstore/book[@category='web']/title[@lang='en']";
        String titleLangValue = (String) xPath.evaluate(titleLangXpath, document, XPathConstants.STRING);
        System.out.println(titleLangValue);
​
        //获取bookstore节点下book属性category值为web下的第二个title节点的文本内容
        String titleXpath="/bookstore/book[@category='web'][2]/title/text()";
        String titleValue = (String) xPath.evaluate(titleXpath, document, XPathConstants.STRING);
        System.out.println(titleValue);
​
        //获取bookstore下book属性category值为cooking的title的lang属性的值
        String titleLangAttrXpath="/bookstore/book[@category='cooking']/title/@lang";
        String titleLangAttrValue = (String) xPath.evaluate(titleLangAttrXpath, document, XPathConstants.STRING);
        System.out.println(titleLangAttrValue);
​
        //获取bookstore节点下所有book的节点集合
        NodeList bookList = (NodeList) xPath.evaluate("/bookstore/book", document, XPathConstants.NODESET);
        //开始遍历bookList
        for (int i=0;i<bookList.getLength();i++){
            Element bookElt = (Element) bookList.item(i);
            String titleValue01 = (String) xPath.evaluate("title", bookElt, XPathConstants.STRING);
            String authorValue = (String) xPath.evaluate("author", bookElt, XPathConstants.STRING);
            String year = (String) xPath.evaluate("year", bookElt, XPathConstants.STRING);
            String price = (String) xPath.evaluate("price", bookElt, XPathConstants.STRING);
            System.out.println(titleValue01+" "+authorValue+" "+year+" "+price);
            System.out.println("-------------------------------------------");
        }
    }
}
复制代码
相关推荐
西柚与蓝莓36 分钟前
【开源开放体系总结】
python
学习使我快乐012 小时前
JS进阶 3——深入面向对象、原型
开发语言·前端·javascript
bobostudio19952 小时前
TypeScript 设计模式之【策略模式】
前端·javascript·设计模式·typescript·策略模式
黄尚圈圈3 小时前
Vue 中引入 ECharts 的详细步骤与示例
前端·vue.js·echarts
浮华似水4 小时前
简洁之道 - React Hook Form
前端
belldeep4 小时前
python:reportlab 将多个图片合并成一个PDF文件
python·pdf·reportlab
正小安6 小时前
如何在微信小程序中实现分包加载和预下载
前端·微信小程序·小程序
FreakStudio6 小时前
全网最适合入门的面向对象编程教程:56 Python字符串与序列化-正则表达式和re模块应用
python·单片机·嵌入式·面向对象·电子diy
丶21366 小时前
【CUDA】【PyTorch】安装 PyTorch 与 CUDA 11.7 的详细步骤
人工智能·pytorch·python
_.Switch7 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j