XML概述
概念
- XML全称为Extensible Markup Language,意思是可扩展的标记语言
- 发明(W3C组织发明)
- 1998年2月发布1.0版本
- 2004年2月又发布1.1版本,但因为1.1版本不能向下兼容1.0版本,所以1.1没有人用
- 2004年2月W3C又发布了1.0版本的第三版
- 我们要学习的还是1.0版本
作用
- 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean className="com.itheima_00_Bean.User">
<property name="username" value="jack"></property>
</bean>
</beans>
类似于java代码
class Bean{
private String username;
private String pws;
//补全set\get方法
}
import com.itheima_00_Bean.User;
public static void main(){
Class clzzz = Class.forName("com.itheima_00_Bean.User");
Object obj = clazz.newInstance();
Method method = clazz.getMethod("setUsername",String.class);
method.invoke(obj,"jack");
}
- 存放数据(在axml文件中保存)
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="p001">
<name>张三</name>
</person>
<person id="p002">
<name>李四</name>
</person>
</persons>
类似于java代码
class Person{
String id;
String name;
}
public void test(){
HashSet<Person> persons = new HashSet<Person>();
persons.add( new Person("p001","张三") );
persons.add( new Person("p002","李四") );
}
- 作为网络传输
分类
- HTML
- 超文本标记语言
- 语法非常严格,不能随意的定义标签
- XML
- 可扩展的标记语言
- 用户可以根据自己的需求,随意的定义标签
XML语法
文档声明
- 格式
-
<?xml version="1.0" encoding="UTF-8"?>
- 文档声明必须为<?xml开头,以?>结束;
- 文档声明必须从文档的0行0列位置开始;
- 文档声明只有2个属性:
- versioin:指定XML文档版本。必须属性,因为我们不会选择1.1,只会选择1.0;
- encoding:指定当前文档的编码。可选属性,默认值是utf-8;
文档内容
元素
<bean 属性名="属性值">元素体</bean>
<开始标签>元素体<结束标签>
- 元素是XML文档中最重要的组成部分,
- 普通元素的结构开始标签、元素体、结束标签组成。例如:<hello>大家好</hello>
- 元素体:元素体可以是元素,也可以是文本,例如:<b><a>你好</a></b>
- 空元素:空元素只有开始标签,而没有结束标签,但元素必须自己闭合,例如:<c attr=”shang” />
- 格式化良好的XML文档,必须只有一个根元素
- 元素命名:
- 区分大小写
- 不能使用空格,不能使用冒号:
- 不建议以XML、xml、Xml开头
属性
- 属性是元素的一部分,它必须出现在元素的开始标签中
- 属性的定义格式:属性名=属性值,其中属性值必须使用单引或双引
- 一个元素可以有0~N个属性,但一个元素中不能出现同名属性
- 属性名不能使用空格、冒号等特殊字符,且必须以字母开头
- 属性和子元素的选择
- 如果你描述的数据是对元素的标识(id),则应该放在属性中
- 如果你描述的数据需要进行再次扩展,必须放在子元素中
注释
- XML的注释,以“<!--”开始,以“-->”结束。注释内容会被XML解析器忽略!
- 注释不能放在文件的第一行
- 注释的快捷键
- 注释 :ctrl + shift + /
- 取消注释 :ctrl + shift + \
转义字符
XML约束
- 约束:对XML文件做一个规范
- 标签名
- 标签的顺序
- 标签的属性
- 标签的子元素
- 分类
- DTD约束(xxx.dtd)
- Schema约束(xxx.xsd)
DTD约束
概念
- DTD(Document Type Definition),文档类型定义,用来约束XML文档,规定XML文档中元素的名称,子元素的名称及顺序,元素的属性
- 实际中很少自己编写DTD约束文档
- 通过框架提供的DTD约束文档,编写对应的XML文档
- 常见框架使用DTD约束有:struts2、hibernate
DTD语法
- 文档声明
- 内部DTD
- 在XML文档内部嵌入DTD,只对当前XML有效
- 内部DTD
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE beans [
... //具体的语法
]>
<beans>
</beans>
- 本地DTD
- DTD文档在本地系统上,公司内部自己项目使用
<?xml version="1.0" encoding="utf-8" ?>
<!--
!DOCTYPE:当前的xml使用一个约束文档(固定的)
beans: 表示当前的xml的根元素 是beans
SYSTEM:固定
"bean.dtd":DTD约束文件的名字
-->
<!DOCTYPE beans SYSTEM "bean.dtd">
<beans>
</beans>
- 外部DTD
- 公共DTD,DTD文档在网络上,一般都有框架提供
<?xml version="1.0" encoding="UTF-8"?>
<!--
!DOCTYPE:当前的xml使用一个约束文档(固定的)
beans: 表示当前的xml的根元素 是beans
PUBLIC :固定
"-//SPRING//DTD BEAN 2.0//EN":DTD标识
"http://www.springframework.org/dtd/spring-beans-2.0.dtd":DTD约束文件的名字
-->
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
</beans>
- 元素声明
定义元素语法:<!ELEMENT 元素名 元素描述>
元素名:自定义
元素描述包括:符号和数据类型
常见符号:? * + () | ,
常见类型:#PCDATA 表示内容是文本,不能是子标签
-
属性声明
属性的语法:(attribute)
<!ATTLIST 属性名
属性名 属性类型约束
属性名 属性类型约束
...
>
元素名:属性必须是给元素添加,所有必须先确定元素名
属性名:自定义
属性类型:ID、CDATA、枚举…
ID : ID类型的属性用来标识元素的唯一性
CDATA:文本类型
枚举:(e1 | e2 | ...) 多选一
约束:
#REQUIRED:说明属性是必须的;required
#IMPLIED:说明属性是可选的;implied
案例
- 根据DTD约束,编写XML文件
<?xml version="1.0" encoding="UTF-8"?>
<!--
模拟spring规范,如果开发人员需要在xml使用当前DTD约束,必须包括DOCTYPE。
格式如下:
<!DOCTYPE beans SYSTEM "bean.dtd">
beans (bean*,import*):beans是根元素,有两个子元素:分别是bean和import
bean和import可以出现0次或者多次
bean和import按照顺序出现
property (#PCDATA) :表示property的元素体是文本
<!ATTLIST bean id ID #REQUIRED //bean有一个属性id, 该属性必须唯一,而且必须写
type CDATA #IMPLIED //属性type 是文本类型,可选的
-->
<!ELEMENT beans (bean*,import*) >
<!ELEMENT bean (property*)>
<!ELEMENT property (#PCDATA)>
<!ELEMENT import (#PCDATA)>
<!ATTLIST bean id ID #REQUIRED
className CDATA #REQUIRED
type CDATA #IMPLIED
>
<!ATTLIST property name CDATA #REQUIRED
value CDATA #REQUIRED
>
<!ATTLIST import resource CDATA #REQUIRED>
- XML编写
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans SYSTEM "bean.dtd"> <beans> <bean id="" className=""></bean> <bean id="" className=""> <property name="" value=""></property> <property name="" value=""></property> </bean> <import resource=""></import> <import resource=""></import> </beans>
Schema约束
- 概念
- Schema是新的XML文档约束,但Schema文档的扩展名为xsd,而不是xml。
- Schema 功能更强大,数据类型更完善,比DTD强大很多,是DTD 替代者;
- Schema 支持名称空间
- 命名空间
案例
根据Schema约束,编写XML文件
<?xml version="1.0" encoding="UTF-8"?>
<!--
模拟spring规范,如果开发人员需要在xml使用当前Schema约束,必须包括指定命名空间。
格式如下:
<beans xmlns="http://www.itcast.cn/bean"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.itcast.cn/bean bean-schema.xsd"
>
-->
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itcast.cn/bean"
xmlns:tns="http://www.itheima.cn/bean"
elementFormDefault="qualified">
<!-- 声明根标签
1. <element> 声明元素(标签)
2. 每一个元素必须确定类型:
complexType 复杂类型:元素可以有子元素,或者有属性
simpleType 简单类型,一般不用,大部分都是复杂类型
3. 需要继续明确子标签出差顺序
<choice> 选择, ()XML Schema 的 choice 元素仅允许包含在 <choice> 声明中的元素之一出现在包含元素中
<sequence> 顺序 ,
<all> 任意
minOccurs 最少出现次数
maxOccurs 最大出现次数,unbounded 不限制(没有边)
4.<attribute>用于给元素声明属性的
use 设置属性使用, optional可选、required必选
-->
<element name="beans">
<complexType>
<choice minOccurs="0" maxOccurs="unbounded">
<element name="bean">
<complexType>
<sequence minOccurs="0" maxOccurs="unbounded">
<element name="property">
<complexType>
<attribute name="name" use="optional"></attribute>
<attribute name="value" use="required"></attribute>
</complexType>
</element>
<element name="yuansu"/>
</sequence>
<attribute name="id" use="required"></attribute>
<attribute name="className" use="required"></attribute>
</complexType>
</element>
<element name="import">
<complexType>
<attribute name="resource" use="required"></attribute>
</complexType>
</element>
</choice>
</complexType>
</element>
</schema>
<?xml version="1.0" encoding="UTF-8"?>
<!-- ns:name space 命名空间:类似于java中包-->
<beans xmlns="http://www.itcast.cn/bean"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.itcast.cn/bean bean-schema.xsd"
>
<bean className="" id="">
<property value=""/>
<yuansu></yuansu>
</bean>
<import resource=""/>
</beans>
XML解析
常见的解析方式
- DOM:要求解析器把整个XML文档装载到内存,并解析成一个Document对象。
- 缺点:XML文档过大,可能出现内存溢出显现。
- 优点:元素与元素之间保留结构关系,故可以进行增删改查操作。
- SAX:是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。并以事件驱动的方式进行具体解析,每执行一行,都将触发对应的事件
- 优点:处理速度快,可以处理大文件
- 缺点:只能读,逐行后将释放资源。
- PULL:Android内置的XML解析方式,类似SAX
解析开发工具包
- JAXP:sun公司提供支持DOM和SAX开发包
- JDom:dom4j兄弟
- jsoup:一种处理HTML特定解析开发包
- dom4j:比较常用的解析开发包,hibernate底层采用
案例1 : 解析XML文件
- 导入第三方jar包
- dom4j-1.6.1.jar
<?xml version="1.0" encoding="utf-8" ?>
<书架>
<书 ISBN = "IT12306">
<书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>39.00元</售价>
</书>
<书 ISBN = "IT10086">
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>199.00元</售价>
</书>
</书架>
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class ParseXML {
public static void main(String[] args) throws Exception {
// 1.创建SAXReader对象
SAXReader sr = new SAXReader();
// 2.将XML文件读取到内存
Document document = sr.read("books.xml");
// 3.获取根元素
Element rootElement = document.getRootElement();
// 4.获取根元素的子元素
List<Element> elements = rootElement.elements();
// 5.遍历子元素
for (Element element : elements) {
// 5.1获取书的属性值
String attr = element.attributeValue("ISBN");
System.out.println(attr);
// 6.获取书的子元素
List<Element> es = element.elements();
// 7.遍历集合
for (Element e : es) {
// 8.获取元素的文本值
String text = e.getText();
System.out.println("\t" + e.getName() + " : " + text);
}
}
}
}
案例2 : 修改XML文件
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="410482">
<name>liuliu</name>
</person>
</persons>
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class UpdateXMLFile {
public static void main(String[] args) throws Exception {
// 1.创建SAXReader对象
SAXReader sr = new SAXReader();
// 2.读取文件数据到内存
Document document = sr.read("persons.xml");
// 3.获取根元素
Element rootElement = document.getRootElement();
// *********************1.修改id的属性值*********************
// 获取person元素对象
Element element = rootElement.element("person");
// 获取id属性对象
Attribute attribute = element.attribute("id");
// 修改属性的值
attribute.setText("88888888");
// *********************2.添加address属性*********************
element.addAttribute("address", "北京");
// *********************3.修改name的文本值*********************
Element name = element.element("name");
name.setText("liuyan");
// *********************4.添加age元素*********************
Element age = element.addElement("age");
age.setText("35");
// *********************5.添加age元素*********************
Element worker = rootElement.addElement("worker");
worker.setText("工人");
// 将修改后的xml树(document)写入文件
writeToXMLFile(document);
}
private static void writeToXMLFile(Document document)
throws FileNotFoundException, UnsupportedEncodingException, IOException {
// 创建字节输出流
OutputStream os = new FileOutputStream("persons.xml");
// 获取输出的指定格式
OutputFormat format = OutputFormat.createPrettyPrint();
// 设置编码 ,确保解析的xml为UTF-8格式
format.setEncoding("UTF-8");
// XMLWriter 指定输出文件以及格式(输出流,格式)
XMLWriter writer = new XMLWriter(os, format);
// 把document写入xmlFile指定的文件(可以为被解析的文件或者新创建的文件)
writer.write(document);
writer.flush();
writer.close();
}
}
结果: