入门
XML文件:XML是可扩展标识语言,(Extensible Markup Language)就是开发者在符合XML命名规则的基础之上,可以根据自己的需求定义自己的标签。
XMl文件的作用:主要是用来存储数据。
解析XML文件的方法:DOM、DOM4J(DOM for Java)、SAX
前两种是把XML文件读取到内存中然后再解析。DOM解析用起来复杂且繁琐。所以一般选择后两种方法。
SAX是事件驱动型,边读边解析。SAX适用于解析大的XML文件。
Dom4j解析xml文件
导入Dom4j.jar包
Dom4j常用的对象:
SAXReader:读取xml文件到Document树结构文件对象。
Document:是一xml文档对象树,类比HTML文档对象。
Element:元素结点。通过Document对象可以查找单个元素。
Dom4j解析步骤:
第一步:创建解析器
SAXReader reader=new SAXReader();
第二步:Document对象:通过解析器read方法获取。
Document doc=reader.read(“studentInfo.xml”);
第三步:获取xml根节点
Element root=doc.getRootElement();
第四步:遍历解析子节点
实例一:解析student.xml文件
XML文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student>
<name>吴飞</name>
<college>java学院</college>
<telephone>62354666</telephone>
<notes>男,1982年生,硕士,现就读于北京邮电大学</notes>
</student>
<student>
<name>李雪</name>
<college>C++学院</college>
<telephone>62358888</telephone>
<notes>男,1987年生,硕士,现就读于中国农业大学</notes>
</student>
<student>
<name>Jack</name>
<college>PHP学院</college>
<telephone>66666666</telephone>
<notes>我是澳洲人</notes>
</student>
<student>
<name>Lucy</name>
<college>Android学院</college>
<telephone>88888888</telephone>
<notes>我是美国人</notes>
</student>
</students>
DOM4j解析代码如下:
package com.sh.xml;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import javax.swing.text.ElementIterator;
import java.util.Iterator;
public class Dom4jTest {
public static void main(String[] args) {
try {
//创建解析器
SAXReader reader=new SAXReader();
//通过解析器的read方法将配置文件读取到内存中,生成一个Document[org.dom4j]对象树
Document document=reader.read("conf/students.xml");
//获取根节点
Element root=document.getRootElement();
//开始遍历根节点
// for(int i=0;i<root.get) 无法通过for循环遍历
for(Iterator<Element> rootIter = root.elementIterator();rootIter.hasNext();)
{
Element studentElt=rootIter.next();
/*<student>
<name>吴飞</name>
<college>java学院</college>
<telephone>62354666</telephone>
<notes>男,1982年生,硕士,现就读于北京邮电大学</notes>
</student>*/
//当前获取到这些,继续遍历其中各个元素
for(Iterator<Element> innerIter=studentElt.elementIterator();innerIter.hasNext();){
Element innerElt=innerIter.next();
//获取该结点元素的文本内容
String innerValue=innerElt.getStringValue();
System.out.println(innerValue);
}
System.out.println("-------------------------------");
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
解析结果:
SAX方式解析xml文件:事件驱动,边度边写
优点:无需将整个文档加载到内存中,所以内存消耗少,适合解析特大文件
SAX解析四步曲:
(1)创建解析器工厂:通过newInstance()方式获取
SAXParserFactory saxParserFactory=SAXParserFactory.newInstance();
因为他的构造方法受到了保护,所以要用newInstance()来创建该对象。
由于解析器必须由SAXParserFactory 类创建,所以必须创建SAXParserFactory
(2)创建解析器:
SAXParser saxParser=saxParserFactory.newSAXParser();
实例二:解析Persons.xml文件输出其中内容
package com.sh.xml;
import javafx.scene.effect.Blend;
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 {
//使用jdk,无需第三方包
public static void main(String[] args) {
try {
//创建解析器工厂
SAXParserFactory saxParserFactory=SAXParserFactory.newInstance();
//创建解析器
SAXParser saxParser=saxParserFactory.newSAXParser();
//通过解析器的parse方法
//param: 文件,DefaultHandler
saxParser.parse("conf/persons.xml",new MyDefaultHandler());
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class MyDefaultHandler extends DefaultHandler{
//重写其中 startElement\endElement\characters方法
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// 解析xml文件开始标签并输出
System.out.print("<"+qName+">");
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// 解析xml文件结束标签并输出
System.out.print("</"+qName+">");
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// 解析中间内容
System.out.print(new String(ch,start,length));//有参构造字符串
}
}
xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<person>
<p1>
<name>zhangsan</name>
<age>20</age>
</p1>
<p1>
<name>wangwu</name>
<age>29</age>
</p1>
</person>
解析结果:
使用Dom4j的XPath解析xml文件
Xpath使用路径表达式来选取xml文档种的节点或节点集。结点是通过路径(path)或者步(steps)来选取
具体可以在官方语法地址学习。
xpath语法选取结点
bookstore.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!--
1.获取bookstore节点下book属性category值为web下的第二个title节点的文本内容
bookstore -> book[@category='web'][2] -> title
xpath路径:/bookstore/book[@category='web'][2]/title/text()
2.获取bookstore节点下book属性category值为web的titile属性为en的节点内容
bookstore -> book[@category='web'] -> title[@lang='en']
xpath路径:/bookstore/book[@category='web']/title[@lang='en']/text()
3.获取bookstore下book属性category值为cooking的title的lang属性的值
bookstore -> book[@category='cooking'] -> title ->@lang
xpath路径:/bookstore/book[@category='cooking']/title/@lang
4.获取bookstore节点下所有book的节点集合
/bookstore/book
-->
<bookstore>
<book category="children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
<book category="web">
<title lang="uk">XQuery Kick Start</title>
<author>James McGovern</author>
<year>2003</year>
<price>49.99</price>
</book>
</bookstore>
选择结点:xpath使用路径表达式在XML文档中选取结点。节点是通过沿着路径或者step来选取的。下面列出最有用的路径表达式:
实例:在下面的表格中,我们已经列出了一些路径表达式以及表达式的结果:
text()获取文本内容函数
示例一:获取sys-config.xml文件的配置信息
准备工作:
(1)导入dom4j-1.6.1.jar和jaxen-1.1-beta-7.jar
(2)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>
第一步:通过SAXReader获取解析器
SAXReader reader=new SAXReader();
第二步:通过解析器的read方法获取Document对象
Document doc=reader.read(“sys-config.xml”);
第三步:通过xpath语法获取driver-name结点
Element driverNameElt = doc.selectObject(“/config/database-info/driver-name”);
String driverName= driverNameElt.getStringValue();
package com.sh.xml;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class SysConfigParser {
public static void main(String[] args) {
try {
//创建解析器
SAXReader reader=new SAXReader();
//通过解析器的read方法将配置文件读取到内存中,生成Document
Document doc=reader.read("conf/sys-config.xml");
//driver-name结点元素的路径:config->database-info/driver-name
//driver-name结点元素的xpath路径:/config/database-info/driver-name
Element driverNameElt=(Element) doc.selectSingleNode("/config/database-info/driver-name");
//获取driverNameElt结点元素对象的文本内容
String driverName=driverNameElt.getStringValue();
System.out.println(driverName);
//url结点元素路径:config->database-info->url
//url结点元素xpath路径:/config/data-base-info/url
//:config//url
//://url
Element urlElt=(Element)doc.selectSingleNode("//url");
String url=urlElt.getStringValue();
System.out.println(url);
//user结点元素路径:config-database-info-user
//config//user
user
//config/database-info/user
Element userElt=(Element)doc.selectSingleNode("//user");
String user=userElt.getText();//获取文本
System.out.println(user);
Element passwordElt=(Element)doc.selectSingleNode("//password");
String password=passwordElt.getTextTrim();
System.out.println(password);
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
示例二:解析server.xml文件:获取端口号
准备server.xml
<?xml version="1.0" encoding="UTF-8"?>
<server>
<service>
<connector port="8080"></connector>
</service>
</server>
第一步:创建 SAXReader 解析器
SAXReader reader = new SAXReader();
第二步:通过解析器 read 方法获取 Document 对象
Document document = reader.read(“server.xml”);
第三步:通过 xpath 语法获取 connector 节点
Element connectorElt = document.selectSingleNode(“/server/service/connector”);
第四步:获取 connector 节点的 port 属性对象
Attribute portAttr = connector.attribute(“port”);
String portStr = portAttr.getStringValue();
package com.sh.xml;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class ServerParser {
public static void main(String[] args) {
try {
SAXReader saxReader=new SAXReader();
Document doc=saxReader.read("conf/server.xml");
//获取connector结点元素对象的xpath路径:/server/service/connector
Element connectorElt=(Element)doc.selectSingleNode("//connector");
//获取connector结点元素对象的port属性
Attribute portAttr=connectorElt.attribute("port");
//获取portAttr属性对象的值(两种方法)
String port=portAttr.getStringValue();
String portValue=connectorElt.attributeValue("port");
System.out.println(port);
// System.out.println(portValue);
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
示例三:解析books.xml文件(org.w3c.dom.Document)
准备books.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year> <price>29.99</price>
</book> <book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year> <price>30.00</price>
</book> <book category="web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book> <book category="web">
<title lang="uk">XQuery Kick Start</title>
<author>James McGovern</author>
<year>2003</year>
<price>49.99</price>
</book>
</bookstore>
第一步:通过 DocumentBuilderFactory 获取解析工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
第二步:获取解析器
DocumentBuilder builder = builderFactory.newDocumentBuilder();
第三步:通过解析的 parser 方法获取 Document 对象
Document document = builder.parse(new File(“books.xml”));
第四步:获取 XPath 对象
XPath xPath = XPathFactory.newInstance().newXPath();
//获取 bookstore 节点下 book 属性 category 值为 web 下的第二个 title 节点的文本内容
xPath.evaluate("/bookstore/book[@category=‘web’[2]/title/text()",document,XPathConstants.STRING);
//获取 bookstore 节点下 book 属性 category 值为 web 的 titile 属性为 en 的节点内容
xPath.evaluate("/bookstore/book[@category=‘web’]/title[@lang=‘en’]/text()",document, XPathConstants.STRING)
获取bookstore下book属性category值为cooking的title的lang属性的值
xPath.evalute(“/bookstore/book[@category=’cooking’]/title/@lang”,document,
XPathConstants.STRING);
获取 bookstore 节点下所有 book 的节点集合
NodeList books = (NodeList)xPath.evaluate(“/bookstore/book”,document,
XPathConstants.NODESET);
//遍历 books 节点
for(int i = 0; i < books.getLength(); i++){}
//获取 book 节点
Node book = books.item(i)
获取 book 标签子节点 title 的文本内容
xPath.evaluate(“title/text()”,book, XPathConstants.STRING);
package com.sh.xml;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class MyXPathTest {
/**
* @param args
*/
public static void main(String[] args) {
try {
//创建解析工厂
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
//创建解析器
DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
//通过解析器读取配置文件,生成一个Document[org.w3c.dom]对象树
Document document = builder.parse("conf/bookstore.xml");
//创建XPath对象
XPath xPath = XPathFactory.newInstance().newXPath();
// 1.获取bookstore节点下book属性category值为web下的第二个title节点的文本内容
// bookstore -> book[@category='web'][2] -> title
// xpath路径:/bookstore/book[@category='web'][2]/title/text()
String titleXpath = "/bookstore/book[@category='web'][2]/title/text()";
String titleValue = (String) xPath.evaluate(titleXpath, document, XPathConstants.STRING);
System.out.println(titleValue);
// 2.获取bookstore节点下book属性category值为web的titile属性为en的节点内容
// bookstore -> book[@category='web'] -> title[@lang='en']
// xpath路径:/bookstore/book[@category='web']/title[@lang='en']/text()
String titleLangXpath = "/bookstore/book[@category='web']/title[@lang='en']/text()";
String titleLangValue = (String) xPath.evaluate(titleLangXpath, document, XPathConstants.STRING);
System.out.println(titleLangValue);
// 3.获取bookstore下book属性category值为cooking的title的lang属性的值
// bookstore -> book[@category='cooking'] -> title ->@lang
// xpath路径:/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);
// 4.获取bookstore节点下所有book的节点集合
// /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("---------------");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}