目录
XML文档
一、XML文件
二、Dom4J解析XML文件
三、Sax解析XML文件
四、使用Dom4j的XPath解析XML文件
4.1XPath语法
4.2 获取sys-config.xml文件的配置信息
4.3 获取server.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("-------------------------------------------");
}
}
}