1. XML概述
历史:
- GML :Generalized Markup Language 通用标记语言
- SGML :Standard Generalized Markup Language 标准通用标记语言,对GML的完善
- HTML :Hyper Test Markup Language 超文本标记语言
- GML :Extensible Markup Language可拓展标记语言
概念:Extensible Markup Language 可扩展标记语言
可拓展性:标签都是自定义的。
功能
- 储蓄数据
- 配置文件
- 在网络中传输
- 储蓄数据
xml和html的区别
xml标签都是自定义的,html标签都是预定义的
xml的语法严格,html语法松散
xml是储存数据的,html是展示数据的。
2. 基本语法
文档声明
- 以
.xml结尾的 - 以
<?xml version='XX' [encoding= "XXX"] [standalone="XX"]?>开头,包括版本类型,编码格式。 - version:版本号,必须的属性
- encoding:编码方式。告知解析引擎当前文档使用的字符集,默认值:ISO-8859-1
- standalone:是否独立
- 取值:
- yes:不依赖其他文件
- no:依赖其他文件
- 取值:
- 以
标签 Tag
- 标记标签:XML文档的主要组成部分
- 语法
<标签名>....</标签名> - 标签必须成对存在:包含一个开始标签和一个结束标签
- 开始标签:
<标签名> - 结束标签:
</标签名> - 开始标签和结束标签标签名必须相同。
- 开始标签和结束标签范围之间的部分叫做标签体,可以包含一些内容。
- 标签体中可以出现子标签,也可以出现纯文本的信息。
元素Element
根元素
标签(元素,节点):只强调开始标签和结束标签以及属性,并不重视标签体中包含什么信息
标签内容
元素:代表从开始标签开始、到结束标签之间所包含的所有内容,称之为一个元素。
元素命名规则
以字母或
_开头后面可以根字母,数字,
_,-或.大小写敏感
不能是保留字
没有长度限制
属性 Attribute
对标签/元素进行额外的附加说明。
属性声明在标签的头部(开始标签)。
id属性值唯一
以键值对的形式存在。
属性值必须要加双引号。
可有有多组属性,每组属性之间使用空格分隔
1
2
3
4
5
6
7
8
9
10<student id="1001" age="22" teacher="2001,tom,22,male">
<name>tom</name>
<gender>male</gender>
<teacher>
<id>2001</id>
<name>tom</name>
<age>22</age>
<gender>male</gender>
</teacher>
</student>
注释
1
2
3
4
5<!-- 单行注释 -->
<!--
多行注释
多行注释
-->实体
- 概念:XML文件中的有些字符不能直接表示出来例如:
<,为了表示他们我们可以借助实体来完成<———-><>———->>'———->'"———->"&———->&
- 概念:XML文件中的有些字符不能直接表示出来例如:
文本
CDATA区:在该区域中的数据会被原样展示
1
<![CDATA[ 数据 ]]>
如何编写一个有效的XML文档
两点要求:- 必须是一个结构良好的XML文档
- 必须使用DTD或者XSD约束文档语义
DTD文档约束
xml本身存在很高的灵活度,所以导致每个程序编写的xml文件差异较大,导致标准不能得到统一,解析的时候难度较大。
需要使用DTD对文档内容进行约束。
约束:制定规则,哪些内容可以出现,哪些内容不能出现….
内部式
内部:被约束的xml文件的内部,DTD代码全部定义在xml文件中
语法
1
元素声明:允许出现哪些元素、不允许出现哪些元素、元素必须按照什么顺序排列、每种元素能够出现多少次、元素中必须拥有哪些属性、属性是什么类型、有无默认值、是否必要……
使用ELEMENT来定义元素
- 语法
1
2
3
4<!ELEMENT 元素名称 类型>
<!ELEMENT 元素名称 内容>
<!ELEMENT note (to,from,heading,body)>
<!--在node元素中只能出现to、from、heading、body子元素-->数量词:用于定义某个元素可以出现多次 加在元素名称后边,代表该元素可以出现多少次
+:可以出现一次或者多次,至少出现一次?:可以出现零次或者一次*:可以出现零次或多次,任意次数|:多个元素中选一个#PCDATA:元素内容必须是解析器会解析的文本字符串信息约束元素不能有子元素,只能包含纯文本如果给某一个元素声明了#PCDATA类型的约束,那么这个元素不再能够拥有子元素。
EMPTY和ANY
1
2
3
4
5
6
7
8<!ELEMENT 元素名称 EMPTY>
<!--元素必须是空元素。
空元素:开始标签和结束标签之间没有任何内容
-->
<hello></hello>
<!ELEMENT 元素名称 ANY>
<!--元素中包含的可以使任意内容。-->
ATTLIST用来定义属性
- 格式:
<!ATTLIST 元素名 属性名 属性类型 默认值> - 属性类型
ID:属性值必须唯一,属性值必须满足命名规则enumerated:(枚举值1|枚举值2|枚举值3….)属性CDATA:属性值为字符
- 属性默认值
#REQUIRED:属性值必须出现在元素的开头标签中#IMPLIED:属性可以不出去,并且当他不出现的时候没有默认值implieddefault-value:属性可以不出现,并且当他不出现的时候有默认值的,二该属性的默认值就是atttibute-value#FIXED:属性可以不出现,但是如果出现的话必须是指定的属性值,不出现的话也是指定的默认值
- 格式:
外部式
把DTD单独定义在一个独立
.dtd的文件中在xml文件中通过简要的声明将这个外置的DTD文件引入进来。
<!DOCTYPE 根标签名 PUBLIC "dtd文件名字" "dtd文件的位置URL">
使用Java程序解析xml文档的方式
SAX 基于事件驱动式、类似爬虫式的解析方式
- SAX弊端是不方便对整个文档进行随机访问
- 优点是节省内存
DOM Document Object Model
在开始读取数据之前,先把整个xml文档解析一遍,加载到内存中,变成一棵文档树形结构。
优点:操作方便,可以对文档进行CRUD的所有操作
缺点:占内存
这两种解析方式都是JDK中原生的解析方式
xml常见的解析器:
- JAXP:sun公司提供的解析器,支持dom和sax两种思想
- DOM4J:一款非常优秀的解析器
- Jsoup:jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
- PULL:Android操作系统内置的解析器,sax方式的。
dom4j Dom for Java
第三方的解析xml的工具,开源、免费
如果需要使用第三方的工具或者框架,首先需要导入依赖。
- 先把jar文件复制到工程目录下,放在哪里都可以
- 想把这个jar文件真正当成依赖文件使用,还需要把他添加到类加载路径中。
jar右击-->Build Path-->Add to Build Path
语法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
// import的时候注意:可能出现很多类名重复的情况
// 导的所有的包都是org.dom4j包下
import org.dom4j.io.SAXReader;
// 解析cities.xml
public class Dom4jDemo {
public static void main(String[] args) throws Exception {
// 第一步、创建Dom4j解析器对象SAXReader
SAXReader reader = new SAXReader();
// 第二步、让reader读取文档,能够把一个文档读取成一个树形结构对象
// 这个doc对象已经包含了文档当中所有的内容
Document doc = reader.read("src/com/briup/xml/cities.xml");
// 第三步、获取文档的根元素
Element root = doc.getRootElement();
// 第四步、获取根元素下的所有直接子元素也就是要获取所有的<city>
List<Element> elements = root.elements();
// 第五步、遍历这个集合,操作每一个<city>
for(Element element:elements) {
Element nameEle = element.element("name");
Element codeEle = element.element("area-code");
String name = nameEle.getText();
String code = codeEle.getText();
System.out.println("城市名:" + name + ","
+ "区号:" + code);
}
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<cities>
<city>
<name>北京市</name>
<area-code>010</area-code>
</city>
<city>
<name>上海市</name>
<area-code>021</area-code>
</city>
<city>
<name>天津市</name>
<area-code>022</area-code>
</city>
<city>
<name>重庆市</name>
<area-code>023</area-code>
</city>
</cities>