什么是XML:
1.可扩展标记语言
2.编写XML就是编写标签,与HTML非常相似,扩展名为.xml
3.良好的人机可读性
XML与HTML的比较
1.XML与HTML非常相似,都是编写标签
2.XML没有预定义标签,HTML存在大量的预定义标签
3.XML重在保存与传输数据,HTML用于显示信息
XML的用途
1.Java程序的配置描述文件
2.保存程序产生的数据
3.网络间的数据传输
XML文档结构
1.第一行必须是XML声明
2.对于整个文档来说只能有且只有一个根节点
3.XML标签书写规则与HTML相同
XML声明
XML声明说明XML文档的基本信息,包括本号与字符集,在XML第一行。
<?xml version="1.0" encoding="utf-8"?>
例子:
XML
<?xml version="1.0" encoding="UTF-8"?>
<!-- 人力资源管理系统 -->
<hr>
<employee no="3309">
<name>张三</name>
<age>31</age>
<salary>4000</salary>
<departemt>
<dname>会计部</dname>
<address>XX大厦-B103</address>
</departemt>
</employee>
<employee no="3310">
<name>李四</name>
<age>23</age>
<salary>3000</salary>
<departemt>
<dname>工程部</dname>
<address>XX大厦-B104</address>
</departemt>
</employee>
</hr>
XML标签书写规则
1.合法的标签名
标签名要有意义
建议使用英文,小写字母,单词之间使用"-"分割
建议多级标签之间不要存在重名
<abc>abc</abc>//×
<考试$>数学期末</考试$>//×
<class><class>班级</class></class>//×
<shop-cart><item>相册</item></shop-cart>//√
2.适当的注释与缩进
适当的注释与缩进可以让XML文档更容易阅读
3.合理使用属性
标签属性用于描述标签不可或缺的信息
对标签分组或者为标签设置ID时常用属性表示。
<shop-cart>
<item sn="771938" category="电器">
<name>XX空调</name>
<price>2000.00</price>
<num>1</num>
</item>
</shop-cart>
<shop-cart>
<item sn="890321" category="食品">
<name>法式面包</name>
<price>10.00</price>
<num>5</num>
</item>
</shop-cart>
4.特殊字符与CDATA标签
处理特殊字符
标签体中,出现"<"、">"特殊字符,会破坏文档结构。
例如:
<exam>
<question>1+4<3是否正确?</question>
<question>3+5>8是否正确?</question>
</exam>
解决方法:
①.使用实体引用。
&It;
= < = 小于
>
= > = 大于
&
= & = 和号
'
= ’ = 单引号
"
= " = 双引号
修改后:
<exam>
<question>1+4&It;3是否正确?</question>
<question>3+5>8是否正确?</question>
</exam>
②.使用CDATA标签。
CDATA指的是不应由XML解析器进行解析的文本数据
从""结束
例如:
<lesson>
<content>
<![CDATA[
<body>
<a href="index.html">首页</a>
</body>
]]>
</content>
</lesson>
被框选的字符串不做解析原意输出
5.有序的子元素
在XML多层嵌套的子元素中,标签前后顺序因保持一致。
XML语义约束之DTD
文档类型定义
DTD文件的扩展名为.dtd
例如:
hr.dtd
<!ELEMENT hr(employee+)>
<!ELEMENT employee(name,age,salary,department)>
<!ATTLIST employee no CDATA"">
<!ELEMENT name(#PCDATA)>
...
DTD定义节点
1.利用DTD中的标签,我们可以定义XML文档中允许出现的节点及数量,以hr.xml为例:
[1]
定义hr节点下只允许出现1个employee子节点。
[2]
employee节点下必须包含以下四个节点,且按顺序出现。
[3]
定义name标签体只能是文本,#PCDATA代表文本元素
DTD定义节点数量
1.如某个子节点需要多次重复出现,则需要在子节点后增加相应的描述符。
例如:
[1]
hr节点下最少出现1个employee子节点。
[2]
hr节点下可出现0…n个employee子节点。
[3]
hr节点下最多出现1个employee子节点。
XML引用DTD文件
在XML中使用标签来引用DTD文件
书写格式:
实例:
例:
XML(完整XML见上)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hr SYSTEM "hr.dtd">
<!-- 人力资源管理系统 -->
<hr>
<employee no="3309">
<name>张三</name>
<age>31</age>
...
DTD
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT hr (employee+)>
<!ELEMENT employee (name,age,salary,departemt)>
<!ATTLIST employee no CDATA "">
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT salary (#PCDATA)>
<!ELEMENT department (dname,address)>
<!ELEMENT dname (#PCDATA)>
<!ELEMENT address (#PCDATA)>
XML语义约束之Schema
Schema比dtd更复杂 高级的约束性语言
提供了数据类型 格式限定 数据范围等特性
Schema 是w3c标准
Schema文件以.xsd结尾
例:
XML
<?xml version="1.0" encoding="UTF-8"?>
<!-- 人力资源管理系统 -->
<hr xmlns:xsi="http://www.w3c.org/2001/XMLSchema-instance" xsi.noNamespaceSchemaLocation="hr.xsd">
<employee no="3309">
<name>张三</name>
<age>31</age>
...
Schema
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema">
<element name="hr">
<!-- complexType标签含义是复杂节点,包含子节点时必须使用这个标签 -->
<complexType>
<!-- 顺序显示sequence -->
<sequence>
<!-- 最少 minOccurs,最多 maxOccurs -->
<element name="employee" minOccurs="1" maxOccurs="9999">
<complexType>
<sequence>
<element name="name" type="string"></element>
<element name="age">
<!-- simpleType对age进行约束,限定 restriction,最小minInclusive,最大maxInclusive -->
<simpleType>
<restriction base="integer">
<minInclusive value="18"></minInclusive>
<maxInclusive value="60"></maxInclusive>
</restriction>
</simpleType>
</element>
<element name="salary" type="integer"></element>
<element name="departmrnt">
<complexType>
<sequence>
<element name="dname" type="string"></element>
<element name="address" type="string"></element>
</sequence>
</complexType>
</element>
</sequence>
<!-- attribute添加属性, required(必须存在) -->
<attribute name="no" type="string" use="required"></attribute>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
DOM 文档对象模型
om4j
1.Dom4j是一个易用的、开源的库,用于解析XML。它应用于Java平台,具有性能优异、功能强大和极其易使用的特点。
2.Dom4j将XML视为Document对象。
3.XML标签被Dom4j定义为Element对象
Dom4j遍历XML
项目中新建lib文件,导入jar包(直接拖入即可)
然后jar包上右击Build Path—>Add Build Path
代码:类名HrReader
package com.imooc.dom4j;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class HrReader {
public void readXml() {
String file= "D:/java/eclipse-workspace/xml/src/hr.xml";
//SAXReader类是读取XML文件的核心类,用于将XML解析后以“树”的形式保存 在内存中。
SAXReader reader = new SAXReader();
try {
Document document = reader.read(file);
//获取XML文档的根节点,即hr标签
Element root = document.getRootElement();
//elements方法用于获取指定的标签集合
List<Element> employees = root.elements("employee");
for(Element employee:employees) {
//element方法用于获取唯一的子节点对象
Element name = employee.element("name");
String empName = name.getText();//getText()方法用于获取标签文本
System.out.println(empName);
System.out.println(employee.elementText("age"));
System.out.println(employee.elementText("salary"));
Element department = employee.element("department");
System.out.println(department.element("dname").getText());
System.out.println(department.element("address").getText());
Attribute att = employee.attribute("no");
System.out.println(att.getText());
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
HrReader reader = new HrReader();
reader.readXml();
}
}
Dom4j更新XML
代码:类名HrWriter
package com.imooc.dom4j;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class HrWriter {
public void WriteXML() {
String file= "D:/java/eclipse-workspace/xml/src/hr.xml";
SAXReader reader = new SAXReader();
try {
Document document = reader.read(file);
Element root = document.getRootElement();
Element employee = root.addElement("employee");
employee.addAttribute("no", "3311");
Element name = employee.addElement("name");
name.setText("李铁柱");
employee.addElement("age").setText("3000");
employee.addElement("salary").setText("3600");
Element department = employee.addElement("departemt");
department.addElement("dname").setText("人事部");
department.addElement("dname").setText("XX大厦-B105");
Writer writer = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
document.write(writer);
writer.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
HrWriter reader = new HrWriter();
reader.WriteXML();
}
}
XPath表达式入门
XPath路径是XML文档中查找数据的语言,掌握XPath可以极大的提高在提取数据时的开发效率
XPath常用基本表达式:
nodename
:选取此节点的所有子节点
/
:从根节点选取
//
:从匹配选择的当前节点选择文档中的节点,不考虑它们的位置
.
:选取当前节点
..
:选取当前节点的父节点
@
:选取属性
XPath表达式使用案例
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元素的所有tltle元素,且其中price元素的值须大于35.00
XPath实验室
Jaxen介绍
1.Jaxen是一个Java编写的开源的XPath库。这是适应多种不同的对象模型,包括DOM、XOM、dom4j和JDOM。
2.Dom4j底层依赖Jaxen实现XPath查询
将Jaxen包添加至项目lib中
代码:
package com.imooc.dom4j;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
public class XPathTestor {
public void xpath(String xpathExp) {
String file= "D:/java/eclipse-workspace/xml/src/hr.xml";
SAXReader reader = new SAXReader();
try {
Document document = reader.read(file);
List<Node> nodes = document.selectNodes(xpathExp);
for(Node node:nodes) {
Element emp = (Element)node;
System.out.println(emp.attributeValue("no"));
System.out.println(emp.elementText("name"));
System.out.println(emp.elementText("age"));
System.out.println(emp.elementText("salary"));
System.out.println("=======================");
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
XPathTestor testor = new XPathTestor();
//testor.xpath("hr/employee");
//testor.xpath("//employee");
//testor.xpath("//employee[salary<4000]");
//testor.xpath("//employee[name='张三']");
//testor.xpath("//employee[@no=3309]");
//testor.xpath("//employee[1]");
//testor.xpath("//employee[last()]");
//testor.xpath("//employee[position()<2]");
testor.xpath("//employee[2]|//employee[3]");
}
}