文章目录
XML简介
Extensible Markup Language(XML),可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。
在电子计算机中,标记指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种的信息比如文章等。它可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 它非常适合万维网传输,提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。是Internet环境中跨平台的、依赖于内容的技术,也是当今处理分布式结构信息的有效工具。早在1998年,W3C就发布了XML1.0规范,使用它来简化Internet的文档信息传输。
1998年2月,W3C正式批准了可扩展标记语言的标准定义,可扩展标记语言可以对文档和数据进行结构化处理,从而能够在部门、客户和供应商之间进行交换,实现动态内容生成,企业集成和应用开发。可扩展标记语言可以使我们能够更准确地搜索内容,更方便地传输内容,更好地描述事物。
什么是可扩展标记语言?
- 可扩展标记语言是一种很像超文本标记语言的标记语言。
- 它的设计宗旨是传输数据,而不是显示数据。
- 它的标签没有被预定义。您需要自行定义标签。
- 它被设计为具有自我描述性。
- 它是W3C的推荐标准。
可扩展标记语言和超文本标记语言之间的差异
- 它不是超文本标记语言的替代。
- 它是对超文本标记语言的补充。
- 它和超文本标记语言为不同的目的而设计:
- 它被设计用来传输和存储数据,其焦点是数据的内容。
- 超文本标记语言被设计用来显示数据,其焦点是数据的外观。
- 超文本标记语言旨在显示信息;而XML旨在传输信息,它是独立于软件和硬件的信息传输工具。
可扩展标记语言无处不在
XML 是各种应用程序之间进行数据传输的最常用的工具。
\
学习Mybatis时,因为要新建配置JDBC的配置文件,接触了xml语言,代码如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--配置环境,这里可以有多套环境,default代表默认的是哪一套-->
<environments default="development">
<!--配置一套环境id,环境的名字-->
<environment id="development">
<!--transactionManager:事务管理;type:jdbc-->
<transactionManager type="JDBC"/>
<!--dataSource 数据源-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--xml中不允许&符号直接出现,我们需要使用 &来代替-->
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--关联映射文件-->
<mappers>
<mapper resource="dao/userMapper.xml"/>
</mappers>
</configuration>
XML用途
- 软件配置:XML可以配置软件信息,如:JavaEE应用中的web.xml
- 存储数据:在没有真正的数据库的前提下,当作小型的数据库用
- 数据传递:在服务端创建XML文件,以IO流的方式传输到客户端,客户端拿到后,提取出XML文件中
XML的语法规则
一个XML文件,加载到内存后,会形成一个倒状的树结构,XML文件内容越多,耗用的内存也就越大
DOM树:
- Document:文档节点,只有一个
- Element:元素节点,标签
- Attribute:属性节点,标签的属性
- Text:文本节点,标签里的内容
- Comment:注释节点
- 文档声明
就是XML文件中第一行代码:
<?xml version="1.0" encoding="UTF-8"?>
version=”1.0”表示解析XML时,采用的版本号,
XML可以用浏览器解析,因为浏览器内置XML解析器,让浏览器采用XML1.0,
版本的解析器来解析,目前1.0最为常用
encoding=”UTF-8”表示解析XML时,采用什么样的解码方式,
注意:文档声明前,不要有空行,空格,注释
- 元素节点
XML中的元素,就是标签,通常情况下,标签有开始就有结束,如果标签无文本的话,就可以简写,但不能乱嵌套,大小写敏感.元素名称做到见名知意,HTML标签是有含义的。
- 属性节点
属性是对标签的附加说明,只出现在开始标签中
- 注释
XML中的注释,注释是给程序员看的,XML解析器忽略,不能注释嵌套
- CDATA字符数据段/区
<sql语句>
<findUser>
<![CDATA[
select * from user where age>30;
]]>
</findUser>
</sql语言>
让XML不按照XML本身的语法来约束,即不将<符号看作是标签的一个部分,而就不报错了
- 转义字符
案例测试
将其写入xml文档
<?xml version="1.0" encoding="UTF-8"?>
<teaching-plan attribute="教学计划">
<course attribute="课程">
<course-name attribute="课程名">大学英语</course-name>
<class-hour attribute="课时">36</class-hour>
<exam-form attribute="考核方式">考试</exam-form>
</course>
<course attribute="课程">
<course-name attribute="课程名">高等数学</course-name>
<class-hour attribute="课时">70</class-hour>
<exam-form attribute="考核方式">考试</exam-form>
</course>
<course attribute="课程">
<course-name attribute="课程名">计算机应用基础</course-name>
<class-hour attribute="课时">108</class-hour>
<exam-form attribute="考核方式">上机考试</exam-form>
</course>
</teaching-plan>
输出结果:直接将xml文件拖到浏览器中
XML语义约束
用于约束XML如何书写的一种技术,这个技术就叫约束模式
约束模式有二个大类别:
- DTD,易学易用,采用DTD语法,功能有限
- Schema,相对难学难用,采用XML语法,功能强大
DTD约束:
<!ELEMENT bookstore (book)>
<!ELEMENT book (title,author,price)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT price (#PCDATA)>
DTD元素的定义语法格式如下:
<!ELEMENT NAME CONTENT>
-
ELEMENT 是关键字
-
NAME 是元素名称
-
CONTENT 是元素类型
DTD不能独立存在,必须嵌入到XML中才有效
嵌入方式有两大类: -
内部方式:DTD和XML在同一个XML文件中
-
外部方式:DTD和XML在不同的文件中,一个在XML中,一个在DTD中,最后通过
- 引用外部本地的DTD,即DTD文件就在你的pc上,
- 引用外部远程的DTD,即DTD文件不在你的pc上,
创建DTD文件
测试代码:
<?xml version="1.0" encoding="UTF-8"?>
<!-- XML的规范 -->
<!-- 必须用空格隔开 -->
<!ELEMENT hr (employee+)>
<!ELEMENT employee (name,age,salary,department)>
<!-- 对属性进行定义 -->
<!ATTLIST employee no CDATA "">
<!-- 纯文本节点 -->
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT salary (#PCDATA)>
<!ELEMENT department (dname,address)>
<!ELEMENT dname (#PCDATA)>
<!ELEMENT address (#PCDATA)>
在XML文件进行导入:SYSTEM代表的是本地文件
<!DOCTYPE hr SYSTEM "hr.dtd">
编程练习:
测试代码:
<?xml version="1.0" encoding="UTF-8"?>
<!-- XML的规范 -->
<!-- 必须用空格隔开 -->
<!ELEMENT teaching-plan (course+)>
<!ELEMENT course (course-name,class-hour,exam-form)>
<!-- 对属性进行定义 -->
<!ATTLIST teaching-plan attribute CDATA "">
<!ATTLIST course attribute CDATA "">
<!ATTLIST course-name attribute CDATA "">
<!ATTLIST class-hour attribute CDATA "">
<!ATTLIST exam-form attribute CDATA "">
<!-- 纯文本节点 -->
<!ELEMENT teaching-plan (#PCDATA)>
<!ELEMENT course (#PCDATA)>
<!ELEMENT course-name (#PCDATA)>
<!ELEMENT class-hour (#PCDATA)>
<!ELEMENT exam-form (#PCDATA)>
XML Schema:
测试代码:
对于下面的添加约束:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 人力资源管理系统 -->
<hr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="hr.xsd">
<employee no="3309">
<name>张三</name>
<age>31</age>
<salary>4000</salary>
<department>
<dname>会计部</dname>
<address>XX大厦-B103</address>
</department>
</employee>
<employee no="3310">
<name>李四</name>
<age>23</age>
<salary>3000</salary>
<department>
<dname>工程部</dname>
<address>XX大厦-B104</address>
</department>
</employee>
</hr>
XML Schema:xsd文件
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema">
<element name="hr">
<!-- complexType标签含义是复杂节点,包含子节点时必须使用这个标签 -->
<complexType>
<sequence>
<element name="employee" minOccurs="1" maxOccurs="9999">
<complexType>
<sequence>
<element name="name" type="string"></element>
<element name="age">
<simpleType>
<restriction base="integer">
<minInclusive value="18"></minInclusive>
<maxInclusive value="60"></maxInclusive>
</restriction>
</simpleType>
</element>
<element name="salary" type="integer"></element>
<element name="department">
<complexType>
<sequence>
<element name="dname" type="string"></element>
<element name="address" type="string"></element>
</sequence>
</complexType>
</element>
</sequence>
<attribute name="no" type="string" use="required"></attribute>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
Java解析XML
DOM4j:
DOM4j遍历XML:首先将 dom4j-2.2.1.jar包 add path到工程中
测试代码:
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 {
//读取XML文件方法
public void readXml(){
String file = "/Users/lcs/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");
//getText()标签用于获取标签文本
String empName = name.getText();
System.out.print(empName);
//获取属性
Attribute att = employee.attribute("no");
System.out.println(" 工号:"+att.getText());
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());
System.out.println("================");
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
HrReader reader = new HrReader();
reader.readXml();
}
}
输出结果:
张三 工号:3309
30
4000
会计部
XX-大厦-B103
================
莉丝 工号:3310
30
5000
工厂部
XX-大厦-B104
================
DOM4j更新XML:写入一个人员信息到hr.xml中
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 = "/Users/lcs/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();
// addElement()方法用于创造一个传入参数类型的元素
Element employee = root.addElement("employee");
// 然后在新建的employee上增加属性
employee.addAttribute("no", "3311");
// 增加子节点
Element name = employee.addElement("name");
name.setText("王五");
employee.addElement("age").setText("37");
employee.addElement("salary").setText("9000");
Element department = employee.addElement("department");
department.addElement("dname").setText("人事部");
department.addElement("address").setText("XX-大厦-A108");
// 已经在内存中完成了编写,接下来将其导入到XML文件
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 hrWriter = new HrWriter();
hrWriter.writeXml();
}
}
查看hr.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hr SYSTEM "hr.dtd"><!-- 人力资源管理系统 -->
<hr>
<employee no="3309">
<name>张三</name>
<age>30</age>
<salary>4000</salary>
<department>
<dname>会计部</dname>
<address>XX-大厦-B103</address>
</department>
</employee>
<employee no="3310">
<name>莉丝</name>
<age>30</age>
<salary>5000</salary>
<department>
<dname>工厂部</dname>
<address>XX-大厦-B104</address>
</department>
</employee>
<employee no="3311">
<name>王五</name>
<age>37</age>
<salary>9000</salary>
<department>
<dname>人事部</dname>
<address>XX-大厦-A108</address>
</department>
</employee>
</hr>
案例测试
写入代码:
package com.imooc.dom4j;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class Plan2Writer {
public void writeXml() {
String file = "/Users/lcs/eclipse-workspace/xml/src/plan2.xml";
// SAXReader类是读取XML文件的核心类,用于将XML解析后以“树”的形式保存在内存中
SAXReader reader = new SAXReader();
try {
Document document = reader.read(file);
// 获取XML文档的根节点,即course标签
Element root = document.getRootElement();
// addElement()方法用于创造一个传入参数类型的元素
Element employee = root.addElement("course");
// 增加子节点
Element name = employee.addElement("course-name");
name.setText("历史");
employee.addElement("class-hour").setText("50");
employee.addElement("exam-form").setText("考试");
// 已经在内存中完成了编写,接下来将其导入到XML文件
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) {
Plan2Writer plan2Writer = new Plan2Writer();
plan2Writer.writeXml();
}
}
打开plan.xml:格式化后结果为
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plan SYSTEM "plan.dtd">
<teaching-plan>
<course>
<course-name>大学英语</course-name>
<class-hour>36</class-hour>
<exam-form>考试</exam-form>
</course>
<course>
<course-name>高等数学</course-name>
<class-hour>70</class-hour>
<exam-form>考试</exam-form>
</course>
<course>
<course-name>计算机应用基础</course-name>
<class-hour>108</class-hour>
<exam-form>上机考试</exam-form>
</course>
<course>
<course-name>历史</course-name>
<class-hour>50</class-hour>
<exam-form>考试</exam-form>
</course>
</teaching-plan>
XPath的使用
Xpath是一个结合DOM4J使用的技术,XPath能够根据字符串,快速定位符合条件的标签
用dom4j+xpath技术,快速定位xml文件中的标签,并取出内容,
导入dom4j中xpath的jar包到classpath中去,
xpath也属于dom4j技术
//第一个/表示xml文件,其它/表示分隔符;
String xpath = "/电视/a/b/c/d";
Element dElement = (Element) xmlDocument.selectStringleNOde();
List<Element> list = xmlDocument.selectNodes(xpath);