1、XML简介
XML全称为Extensible Markup Language,意思是可扩展的标记语言。目前最常用的XML版本为1.0版本
XML文档的基本声明格式:
<?xml version="1.0" encoding="UTF-8"?>
- 1.文档声明必须为<?xml开头,以?>结束,中间没有空格;
- 2.文档声明必须从文档的0行0列位置开始;
- 3.文档声明只有2个属性,格式 属性名= “属性值”,属性值必须使用””
- a)versioin:指定XML文档版本。必须属性,因为我们不会选择1.1,只会选择1.0;
- b)encoding:指定当前文档的编码。可选属性,默认值是utf-8;
XML文档中的注释格式
以<!--开始,以-->结束,注释符号中的内容会被XML解析器忽略
XML文档中的元素/标签/标记
<bean>内容</bean>
- 元素是XML文档中最重要的组成部分,
- 普通元素的结构开始标签、元素体、结束标签组成。例如:<hello>大家好</hello>
- 元素体:元素体可以是元素,也可以是文本,例如:<b><a>你好</a></b>
- 空元素:空元素只有开始标签,而没有结束标签,但元素必须自己闭合,例如:<c/>
- 元素命名:
- 区分大小写
- 不能使用空格,不能使用冒号:
- 不建议以XML、xml、Xml开头
- 格式化良好的XML文档,必须只有一个根元素。
XML文档中的属性
<bean id=”” className=””>
- 属性是元素的一部分,它必须出现在元素的开始标签中
- 属性的定义格式:属性名= ”属性值”,其中属性值必须使用单引或双引
- 一个元素可以有0~N个属性,但一个元素中不能出现同名属性
- 属性名不能使用空格、冒号等特殊字符,且必须以字母开头
XML文档中的转义字符
一些被XML所使用了的字符如果想出现在XML文件中,需要使用XML的转义字符,常用列表如下:
< --- <
> --- >
" --- "
' --- '
& --- &
XML文档中的CDATA区
<![CDATA[任意内容]]>
当大量XML中的内容需要使用到转义字符时,就需要使用CDATA区,该区可以填写除CDATA的结束界定符]]>外的任何内容,如果一定需要出现结束界定符,需要创建两个CDATA区,再加上需要出现的结束界定符符号即可。
2、XML约束
xml约束,即为用来约束xml文件规范的文档,常见的xml约束包括DTD和Schema
1)DTD约束
DTD(Document Type Definition),文档类型定义,用来约束XML文档。规定XML文档中元素的名称,子元素的名称及顺序,元素的属性等。要使用该约束,通常在xml文件的第二行引用.dtd文件即可,格式如下:
<!DOCTYPE beans SYSTEM "bean.dtd">
其中"beans"指的是此xml要使用的根节点的名字,bean.dtd为约束文件名,其余为固定格式
DTD文件引用的三种方式:
a、可以通过在xml内部直接嵌入DTD,只对当前xml有效
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE beans [
... //具体的语法
]>
</beans>
<beans>
b、DTD文档可以直接在项目中读取到时,直接声明文件名即可:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE beans SYSTEM "bean.dtd">
<beans>
</beans>
c、当需要使用网址访问DTD文档时(一般由框架提供),格式如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
</beans>
2)Schema约束
Schema是新的XML文档约束;
Schema要比DTD强大很多,是DTD 替代者;
Schema本身也是XML文档,但Schema文档的扩展名为xsd,而不是xml。
Schema 功能更强大,数据类型更完善
Schema 支持名称空间(类似java的包)
命名空间
如果一个XML文档中使用多个Schema文件,而这些Schema文件中定义了相同名称的元素时就会出现名字冲突。命名空间就是用来处理元素和属性的名称冲突问题。、
声明格式与使用格式:
默认命名空间:<xxx xmlns=””>,使用<标签>
显式命名空间:<xxx xmlns:别名=””>,使用<别名:标签>
3、XML的解析
常见的解析方式有三种,如下:
- DOM:要求解析器把整个XML文档装载到内存,并解析成一个Document对象。
- 优点:元素与元素之间保留结构关系,故可以进行增删改查操作。
- 缺点:XML文档过大,可能出现内存溢出显现。
- SAX:是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。并以事件驱动的方式进行具体解析,每执行一行,都将触发对应的事件。
- 优点:处理速度快,可以处理大文件
- 缺点:只能读,逐行后将释放资源。
- PULL:Android内置的XML解析方式,类似SAX。
常见的解析开发包:
- JAXP:sun公司提供支持DOM和SAX开发包
- JDom:dom4j兄弟
- jsoup:一种处理HTML特定解析开发包
- dom4j:比较常用的解析开发包,hibernate底层采用。
DOM解析的具体方式
XML DOM 将整个XML文档加载到内存,并获得一个Document对象(实际上是一个DOM树),通过Document对象就可以对DOM进行操作,需要使用该解析方式需要导入对应的dom4j包。
通常使用核心类SaxReader加载xml文档获得Document,通过Document对象获得文档的根元素,然后就可以操作了。
常用API如下:
- SaxReader对象
- read(…) 加载执行xml文档
- Document对象
- getRootElement() 获得根元素
- Element对象
- elements(…) 获得指定名称的所有子元素。可以不指定名称
- element(…) 获得指定名称第一个子元素。可以不指定名称
- getName() 获得当前元素的元素名
- attributeValue(…) 获得指定属性名的属性值
- elementText(…) 获得指定名称子元素的文本值
- getText() 获得当前元素的文本内容
以下代码实现的是解析项目中的beans.xml,并打印一些值
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="001" className="cn.itcast.demo.User">
<property name="username" value="jack"></property>
<property name="password" value="123"></property>
</bean>
<bean id="002" className="cn.itcast.demo.Admin">
<property name="username" value="admin"></property>
<property name="password" value="123321"></property>
</bean>
</beans>
public class Dom4JDemo {
public static void main(String[] args) throws DocumentException {
// TODO Auto-generated method stub
//1.把整个要解析的XML文件加载到内存
SAXReader reader = new SAXReader();
//2.会生产一个Documnet对象
Document document =reader.read(new File("beans.xml"));
//3.获取根标签
Element rootEle = document.getRootElement();
//4.获取根标签的子标签
List<Element> beanElements = rootEle.elements();
//5.遍历elements集合
for (Element beanElement : beanElements) {
//6.获取子标签bean的属性
String idValue = beanElement.attributeValue("id");
String classNameValue = beanElement.attributeValue("className");
System.out.println(idValue+".."+classNameValue);
//获取bean的子标签
List<Element> propertyElements = beanElement.elements();
//遍历property标签
for (Element propertyElement : propertyElements) {
//propertyElement Property标签
//获取Property的属性
String nameValue = propertyElement.attributeValue("name");
String valuevalue = propertyElement.attributeValue("value");
System.out.println(nameValue+"==="+valuevalue);
}
}
}
}
运行结果如下:
001..cn.itcast.demo.User
username===jack
password===123
002..cn.itcast.demo.Admin
username===admin
password===123321