继续学习xml,知识点如下:
一、scheam约束
已知xml的约束分为dtd约束和scheam约束。
1.dtd语法:<!ELEMENT 元素名称 约束>
而schema符合xml语法,一个xml中可以有多个schema,多个schema使用名称空间来区分(类似于java包名)
2.dtd里面有CDATA类,但是在scheam里可以支持更多的数据类型,比如,年龄可以直接定义整数类型
3.scheam语法更多更复杂,目前还不能替代dtd、
4.scheam语法:
后缀名:.xsd 根节点:<schema>
其中: xmlns="http://www.w3.org/2001/XMLSchema"
表示是约束文件
targetNamespace="http://www.hahaha.cn/20180730" (可以任意写,不过最好的url)
使用schema 约束文件,直接通过这个地址引入约束文件
elementFormDefault="qualified"
步骤:
(1)看xml中有多少个元素<element>
(2)看简单元素还是复杂元素
如果复杂元素
<element name="Person">
<complexType>
<sequence>
子元素
</sequence>
</complexType>
</element>
简单元素,写在复杂元素里
即:
<elementFormDefaultment name="Person">
<complexType>
<sequence>
<element name="name" type="string"></element>
<element name="age" type="int"></element>
</sequence>
</complexType>
</element>
(3)在被约束文件里,引入约束文件
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.itcast.cn/20180730"
xsi:schemaLocation="http://www.itcast.cn/20180730 1.xsd">,其中:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" :表示其是 被约束 的文件
xmlns="http://www.itcast.cn/20180730":是约束文档里面的targetNamespace
xsi:schemaLocation="http://www.itcast.cn/20180730 1.xsd"> targetNameSpace 空格 约束文档路径
(4)在schema文件中, 有以下标签
<sequence> :出现顺序
<all>:元素只能出现一次
<choice>:只能出现其中一个
<any>:任意元素
且有maxOccurs="unbounded": 元素出现次数------无限,如:
<element name="name" type="string" maxOccurs="unbounded"></element>
(5)可以约束属性, 写在复杂元素里,且写在</complexType>之前
..........
<attribute name="id1" type="int" use="required"></attribute>
</complexType>
name:属性名称 type:属性类型 use:是否必须出现
则<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.itcast.cn/20180730"
xsi:schemaLocation="http://www.itcast.cn/20180730 1.xsd" id1="123">
(6)名称空间
如一个xml文件中引入多个schema文件,可通过命名空间 xmlns:a xmlns:b ,来分别给两个文件命名
当两个schema同时有name属性时,可以通过<a:name>zhangsan</a:name> <b:name>lisi</b:name>来区分
二、sax解析(jaxp)
1. javax.xml.parses包里:SAXParser:解析器类
SAXParserFactory:解析器工厂
SAXParserFactory.newInstance();获取
SAXParserFactory.newSAXParser();
parse(File f,DefaultHandler dh)
两个参数:
第一个参数,xml的路径
第二个参数,事件处理器
2.使用jaxp的sax方式解析xml (能力弱)
* 1.创建解析器工厂
* 2.获取解析器
* 3.执行parse方法
* 4.自己创建一个类,继承DefaultHandler
* 5.重写里面的三个方法
三、 dom4j解析xml
1.dom4j不是javase一部分,所以需要导入jar包
2.首先要得到document
SAXReader reader = new SAXReader();
Document document = reader.read(url);
document 方法:getRootElement(),......
element 方法:getParent() addElement(),......
3.使用dom4j实现增删改操作,需要回写,用到XMLWriter类
XMLWriter xmlWriter=new XMLWriter(new FileOutputStream("src/Day_2/p1.xml"),
OutputFormat.createPrettyPrint()); //较好的格式,有缩进效果
xmlWriter.write(document);
xmlWriter.close();
注意:在其中如果创建添加的元素,且不是在节点尾巴添加,需要利用
DocumentHelper.createElement(......);
四、 dom4j支持xpath的操作
默认情况下,dom4j不支持xpath,
如果想支持,需要 导入jar包
1.xpath形式
可以直接获取到某个元素
第一种形式:
/AAA/BBB/CCC:表示一层一层的,AAA下的BBB下的CCC
第二种形式:
//BBB:表示和这个名词相同,都可以得到(只要名词是BBB,都可以得到)
第三种形式:
/*:表示所有元素
第四种形式:
BBB[1]:第一个BBB元素
BBB[last()]:最后一个BBB元素
第五种形式:
//BBB[@id]:表示只要BBB元素上面有id属性,都可以得到
第六种形式:
//BBB[@id='b1']:表示元素名称是BBB,在BBB上面有id属性,并且id='d1'
等等,详见XPath文档
2.在dom4j里提供了两个方法支持xpath
selectNodes("xpath表达式")
selectSingleNode("xpath表达式")
/**
* (简便了许多)
* 1.得到document
* 2.直接使用selectNodes得到所有name元素
*/
Document document=Dom4jUtils.getDocument(Dom4jUtils.PATH);
List<Node> list=document.selectNodes("//name");
for(Node node:list){
System.out.println(node.getText());
}
五、体会
1. schema约束比dtd约束相对写说,开头部分的写法要复杂不少,不过整体来说schema约束比dtd要方便;schema符合xml语法,而且数据类型也多,逻辑性也要强,各有秋千吧,不过觉得schema约束的实践性更高点;
2.jaxp的sax和dom解析xml的方式比较复杂,而且能力相对弱点,创建解析器前需要创建解析器工厂,等,而相反,dom4j的解析方式会简洁很多,也难怪dom4j解析器的应用最广,而且在实现对xpath的支持后,更为方便;