XML之解析(知识详解即基本使用)

XML解析

1. 了解XML解析

1.1 概念:

XML解析是指将XML文件转换为程序可以处理的数据结构的过程。由于XML是一种用于描述数据结构和信息的语言,因此,通过XML解析,可以将XML文档中的数据转换为程序可以使用的对象或数据。

1.2 解析过程:

XML解析包括两个主要过程:解析器(Parser)将XML文档读取到内存中并构建成树形结构,解析器会根据XML文档的规范对其进行语法和语义的验证;解析器读取完成后,解析器将把XML文档转换为程序可以使用的数据结构,这些数据结构可以便于程序对XML文档中的数据进行访问和处理。

图解:

在这里插入图片描述

1.3 常见的解析技术:

  • DOM解析
  • SAX解析
  • XML
  • Pull解析等

1.4 XML解析图解

在这里插入图片描述

2. XML解析的重要性

2.1 XML解析的主要作用:

  • 读取和处理XML数据:XML解析器可以将XML文档读取到内存中,并将其转换为程序可以处理的数据。程序可以对这些数据进行处理,从而完成各种操作,例如数据编辑、转换、导入导出等。
  • 验证XML文件的合法性:解析器可以验证XML文档的合法性,检查XML文档是否符合XML规范和DTD/Schema定义,如果XML文档中存在错误或不可识别的元素,解析器将报告解析错误。
  • 基于XML文档结构进行操作:XML解析器将XML文档转换为一个树形结构(由元素、属性和文本等元素组成),程序可以依据这个树形结构对XML文档的结构进行操作,例如查询、模糊搜索或基于特定条件过滤等操作。
  • 解析和处理复杂的XML文档:XML是一种灵活和可扩展的数据格式,它具有嵌套和复杂的数据结构。XML解析器可以让程序轻松处理和操作这些复杂的XML文档,使得程序的开发和维护更加容易。

2.2 XML解析的作用域(使用方面):

  • 数据分析和处理:由于XML可以存储和表示复杂的数据结构,因此XML解析器可以用于将XML数据转换为程序可以使用的内部数据结构,从而实现数据的分析和处理。
  • 网络通信:许多Web服务和REST API使用XML作为数据传输的格式,因此程序需要使用XML解析器解析和处理网络传输的XML数据,以便从中提取和处理必要的信息。
  • 数据存储和交换:XML解析器可以将XML数据转换为数据库可用的格式,或者将应用程序中的数据导出为XML文档。这样,开发人员就可以轻松地存储和交换数据,以满足与其他应用程序的数据交换需求。
  • 配置文件:许多应用程序使用XML格式的配置文件来定义系统配置和参数。 XML解析器可将配置文件读取到内存中,并使应用程序能够读取,解释和使用这些参数,以满足程序需求。

总结:总之,XML解析在现代软件开发中扮演着非常重要的角色,能够帮助程序员轻松处理和操作基于XML的数据结构。无论在何种应用场景下,简单且易于理解的XML格式仍然是开发人员最喜欢的数据格式之一。

3. XML解析的综合使用

3.1 Java中配置文件的三种配置位置及读取方式:

3.1.1 同包路径下的读取方式

图示:

在这里插入图片描述

读取方法:

类名.class.getResourceAsStream("配置文件名")

案例1:

package com.YX.Parse;

import java.io.InputStream;
import java.util.Properties;

/**
 * 读取不同路径下的配置文件 1.同包 2.根路径 3.安全路径
 * 
 * @author 86158
 *
 */
public class Demo1 {
	// 打开主程序入口
	public static void main(String[] args) throws Exception {
		// 1. 通过类加载器加载配置文件(同包路径下的),返回的是一个流对象
		InputStream is = Demo1.class.getResourceAsStream("db.properties");
//		实例化Properties工具类,方便调用对应的加载方法
		Properties p = new Properties();
//		让Properties工具类对象加载含有db.properties文件类容所对应的流
//		(将上面创建的流作为参数调用Properties对象的load()方法(加载配置文件))
		p.load(is);
//		输出语句   通过getProperty()方法读取配置文件的内容
		System.out.println("uname:"+p.getProperty("uname"));
		System.out.println("upass:"+p.getProperty("upass"));
	}
}

db.properties配置文件:

在这里插入图片描述

输出结果(如图示):

在这里插入图片描述

3.1.2 根路径下的读取方式

图示

在这里插入图片描述

:如果在根路径下使用同包路径下的读取方式则会报错(如下图所示)

在这里插入图片描述

正确读取根路径下的配置文件的方式

package com.YX.Parse;

import java.io.InputStream;
import java.util.Properties;

/**
 * 读取不同路径下的配置文件 1.同包 2.根路径 3.安全路径
 * 
 * @author 86158
 *
 */
public class Demo1 {
	// 打开主程序入口
	public static void main(String[] args) throws Exception {
//		2.根路径下读取配置文件
		// 通过类加载器加载配置文件(根路径下的),返回的是一个流对象
		InputStream is = Demo1.class.getResourceAsStream("/db.properties");
//		实例化Properties工具类,方便调用对应的加载方法
		Properties p = new Properties();
//		让Properties工具类对象加载含有db.properties文件类容所对应的流
//		(将上面创建的流作为参数调用Properties对象的load()方法(加载配置文件))
		p.load(is);
//		输出语句   通过getProperty()方法读取配置文件的内容
		System.out.println("uname:"+p.getProperty("uname"));
		System.out.println("upass:"+p.getProperty("upass"));
		System.out.println("url:"+p.getProperty("url"));
		System.out.println("driver_Class:"+p.getProperty("driver_Class"));
	}
}

输出结果:

在这里插入图片描述

3.1.3 安全路径下的读取方式(WebContent下的WEB-INF文件夹里)

图示:

在这里插入图片描述

注意事项:当配置文件移至安全路径下时,再用同包路径或根路径下会加载不到配置文件,新建一个jsp文件在安全路径下,运行网页会报404错误。当时如果网页路径退一层则会获取到(如下图所示)

在这里插入图片描述

在这里插入图片描述

安全路径下正确读取配置文件的方式:

新建一个servlet类

package com.YX.Parse;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class YXServlet
 */
@WebServlet("/YXServlet")
public class YXServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 访问安全目录下的配置文件
		InputStream is = request.getServletContext().getResourceAsStream("/WEB-INF/db.properties");
		Properties p = new Properties();
		// 让Properties工具类对象加载含有db.properties文件类容所对应的流
		// (将上面创建的流作为参数调用Properties对象的load()方法(加载配置文件))
		p.load(is);
		// 输出语句 通过getProperty()方法读取配置文件的内容
		System.out.println("uname:" + p.getProperty("uname"));
		System.out.println("upass:" + p.getProperty("upass"));
		System.out.println("url:" + p.getProperty("url"));
		System.out.println("driver_Class:" + p.getProperty("driver_Class"));
	}

}

控制台输出结果

在这里插入图片描述

3.2 XML中获取配置文件下的指定内容

3.2.1 方式:

利用DOM4J解析

3.2.2 方法
方法作用
SAXReader.read(File file)将指定的XML文件读入内存并解析成一个Document对象。
Document.getRootElement()获取XML文件的根节点。
Element.elements()获取当前元素节点下的所有子节点。
Element.attributeValue(String name)获取元素节点的指定属性值。
Element.elementText(String name)获取元素节点的指定子节点的文本值。
Element.addElement(String name)添加一个子节点。
Element.addAttribute(String name, String value)添加一个属性。
Element.setText(String text)设置元素节点的文本。
3.2.3 四大重要类
类名说明
Document文档类,代表整个XML文件。
ElementElement
Attribute属性类,代表XML文件中元素的属性。
Text文本类,代表XML文件中的文本。
3.2.4 DOM4J解析XML的基本流程:
  1. 创建SAXReader对象。
  2. 调用SAXReader对象的read()方法,将XML文件读入内存,并返回一个Document对象。
  3. 通过Document对象获取XML文件中的根节点。
  4. 遍历根节点的所有子节点,获取需要的元素节点及其属性和文本内容。

代码示例:

新建一个XML文档示例

<bookstore>
   <book category="COOKING">
      <title lang="en">Everyday Italian</title>
      <author>Giada De Laurentiis</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
</bookstore>

java代码:

import java.io.File;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class Dom4jExample {
    public static void main(String[] args) {
        try {
            // 创建SAXReader对象
            SAXReader reader = new SAXReader();
            // 读入XML文件并解析
            Document doc = reader.read(new File("books.xml"));
            // 获取XML文件的根节点
            Element root = doc.getRootElement();
            // 遍历根节点下的所有子节点
            List<Element> books = root.elements();
            for (Element book : books) {
                System.out.println("Book Category:" + book.attributeValue("category"));
                System.out.println("Title:" + book.elementText("title"));
                System.out.println("Author:" + book.elementText("author"));
                System.out.println("Year:" + book.elementText("year"));
                System.out.println("Price:" + book.elementText("price"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出结果:

在这里插入图片描述

3.2.5 DOM4J解析XML的进阶使用
  • 增加子节点,并设置属性和文本值
package com.YX.Parse;
import java.io.File;
import java.io.InputStream;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class Demo3 {
    public static void main(String[] args) {
        try {
        	// 通过类加载器加载配置文件(同包路径下的),返回的是一个流对象
        	InputStream is = Demo3.class.getResourceAsStream("books.xml");
            // 创建SAXReader对象
            SAXReader reader = new SAXReader();
            // 读入XML文件并解析
            Document doc = reader.read(is);
            // 获取XML文件的根节点
            Element root = doc.getRootElement();
            // 遍历根节点下的所有子节点
            System.out.println("====================修改前============");
            System.out.println(doc.asXML());
            List<Element> books = root.elements();
            System.out.println("所有子节点=============================");
            for (Element book : books) {
                System.out.println("Book Category:" + book.attributeValue("category"));
                System.out.println("Title:" + book.elementText("title"));
                System.out.println("Author:" + book.elementText("author"));
                System.out.println("Year:" + book.elementText("year"));
                System.out.println("Price:" + book.elementText("price"));

                // 添加一个子节点,并设置属性和文本值
                Element publisher = book.addElement("publisher");
                publisher.addAttribute("name", "PublisherName");
                publisher.setText("PublisherText");
            }

            // 保存修改后的XML文件
            System.out.println("修改后===================================");
            System.out.println(doc.asXML());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出结果:

在这里插入图片描述