XML
1. 概述
XML(eXtensible Markup Language),是一种可扩展的标记语言,类似HTML(超文本标记语言)。
XML技术是W3C组织(World Wide Web Consortium万维网联盟)发布的,目前遵循的是W3C组织于2000年发布的XML1.0规范。(XML从第一个版本发布之后,从来没有更新过,也不需要更新,完美)
XML是一种通用的数据交换格式(关系型数据库),许多系统的配置文件都使用XML格式,JSP文档也逐步向XML语法格式过渡,许多项目都采用XML作为数据交换格式(WebService),典型代表:WebService就是不同的项目,或者不同的语言交换数据的技术;
综上,XML可以传输数据,也可以存储数据
1.1 注意事项
- XML标签命名自定义【推荐英文】,标签名中不能包含空格
- XML空格和换行都表示数据,严格区分大小写
- XML中特殊字符表示的数据需要使用特殊字符编码和HTML一样
- CDATA区中的数据不会被识别为语法
1.2 约束
XML约束的目的:规范XML中书写的内容,XML约束分为:DTD约束、Schema约束
1.2.1 DTD约束
DTD约束文件与XML文件关联
<!DOCTYPE 文档根结点 SYSTEM "DTD文件的URL">
<!DOCTYPE contacts SYSTEM “contacts.dtd”>
DTD细节
<!--contacts下有一个或多个linkman,+代表起码一个-->
<!ELEMENT contacts (linkman+)>
<!--linkman下包含有按顺序的四个标签-->
<!ELEMENT linkman (name,email,address,group)>
<!--给标签内填充数据内容-->
<!ELEMENT name (#PCDATA)>
<!ELEMENT email (#PCDATA)>
<!ELEMENT address (#PCDATA)>
<!ELEMENT group (#PCDATA)>
<!--使用dtd定义属性-->
<!ATTLIST 元素名称 属性名称 属性类型 属性约束>
-
声明一个标签下有嵌套子标签,多个不同标签使用逗号隔开
-
声明标签下是直接的内容,#PCDATA代表数据的意思,官方说法叫被解析的字符数据
属性类型:
-CDATA :表示字符串
-枚举:表示只能出现范围内的一种值
-ID:属性只能以字母下划线开头
属性值的约束:
#REQUIRED:表示必须出现
#IMPLIED:表示该属性可有可无
#FIXED:表示该属性的取值为一个固定值 语法: #FIXED “固定值”
注意:DTD约束中若出现错误,不会报错
1.2.2 Schema约束
Schema约束文件与XML文件关联
<contacts xmlns="http://itsource.cn"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="http://itsource.cn contactsSchema.xsd">
Schema细节
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://itsource.cn" elementFormDefault="qualified">
<!--声明了一个根标签,contacts-->
<xs:element name="contacts">
<!--contacts标签下的元素是复杂类型,也就是包含其他元素-->
<xs:complexType>
<!--规定contacts下元素出现的顺序和次数,maxOccurs代表最大次数-->
<xs:sequence maxOccurs='unbounded'>
<xs:element name="linkman">
<xs:complexType>
<xs:sequence>
<xs:element name='name' type='xs:string' />
<xs:element name='email' type='xs:string' />
<xs:element name='address' type='xs:string' />
<xs:element name='group' type='xs:string' />
</xs:sequence>
<xs:attribute name="id" type="xs:long" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
1.3 DOM模型
DOM(Document Object Model)文档对象模型。直白的讲就是Java程序解析结构化文档(html,xml)的时候,在内存中会形成一个包含当前文档所有内容的层级结构。所以说DOM并不是一门技术,而是一门思想,或者更明确的讲是一门访问结构化文档的一种方式。那么当前我们学过的结构化文档有HTML、XML。DOM模型实际上描述的就是标签之间的层级结构。
2. JAXP解析XML(即原生解析)
2.1 获取Dom对象
- 获取解析器工厂对象
- 解析器工厂对象创建解析器对象
- 解析器解析实体XML文件返回Document对象
//获取DocumentBuilderFactory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//获取DocumentBuilder对象
DocumentBuilder builder = factory.newDocumentBuilder();
//获取dom对象
Document dom = builder.parse(file);
2.2 查询
@Test
public void select(){
//获取第一个name标签
Element item = (Element)root.getElementsByTagName("name").item(0);
//获取name标签里的内容
String content = item.getTextContent();
System.out.println(content);
}
2.3 添加
@Test
public void add(){
//获取第一个student标签
Element item = (Element)root.getElementsByTagName("student").item(0);
//使用dom对象创建sex标签
Element element = dom.createElement("sex");
//给sex标签设置值
element.setTextContent("妖");
//在student标签里添加sex标签
item.appendChild(element);
}
2.4 修改
@Test
public void update(){
//获取第一个sex标签
Element item = (Element)root.getElementsByTagName("sex").item(0);
//修改sex标签里的内容
item.setTextContent("男");
}
2.5 删除
@Test
public void delete(){
//获取第一个sex标签
Element item = (Element)root.getElementsByTagName("sex").item(0);
//获取sex标签的父节点
Node parentNode = item.getParentNode();
//移除子节点
parentNode.removeChild(item);
}
2.6 刷新
进行添加、修改、删除操作后,都要进行刷新操作,将内容回写到文件中
@After
/**
* 刷新操作
* */
public void flush() throws Exception{
//获取TransformerFactory对象
TransformerFactory factory = TransformerFactory.newInstance();
//获取transformer对象
Transformer transformer = factory.newTransformer();
//获取内存中的DOM模型数据
DOMSource source = new DOMSource(dom);
//写入文件
StreamResult result = new StreamResult(file);
transformer.transform(source, result);
System.out.println("回写结束");
}
3. DOM4J解析XML
3.1 Xpath
XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言。XPath基于XML的树状结构,有不同类型的节点,包括元素节点,属性节点和文本节点,提供在数据结构树中找寻节点的能力。XPath 是一门在 XML 文档中查找信息的语言。XPath 用于在 XML 文档中通过元素和属性进行导航
//示例,具体查看API文档
Element tel =(Element)root.selectSingleNode("/class/student[1]/tel");
3.2 获取DOM对象
//获得SAXReder对象
SAXReader reader = new SAXReader();
//调用read方法获取xml的dom对象
dom = reader.read(file);
3.3 查询
@Test
public void select(){
//通过Xpath的方式获取需要查询的节点
Element singleNode =(Element)root.selectSingleNode("/class/student[1]/name");
//System.out.println(singleNode);
//调用getText方法获得该节点的内容
System.out.println(singleNode.getText());
}
3.4 添加
@Test
public void add(){
//通过Xpath的方式获取需要添加到该位置的节点
Element student =(Element)root.selectSingleNode("/class/student[1]");
//System.out.println(student);
//调用addElement添加节点并调用setText方法设置内容
student.addElement("tel").setText("17828110243");
}
3.5 修改
@Test
public void update(){
//通过Xpath的方式获取需要修改的节点
Element tel =(Element)root.selectSingleNode("/class/student[1]/tel");
//调用setText方式修改内容
tel.setText("12331");
}
3.6 删除
@Test
public void delete(){
//通过Xpath的方式获得需要删除的节点
Element tel =(Element)root.selectSingleNode("/class/student[1]/tel");
//获取该节点的父节点并删除该节点
tel.getParent().remove(tel);
}
3.7 刷新
进行添加、修改、删除操作后,都要进行刷新操作,将内容回写到文件中
@After
public void flush() throws IOException{
//获得格式化输出的一个对象
OutputFormat format = OutputFormat.createPrettyPrint();
//构造一个具有良好输出格式的XML输出对象
XMLWriter xmlWriter = new XMLWriter(new FileWriter(file),format);
//将内存中的dom对象写入文件
xmlWriter.write(dom);
//关闭流资源
xmlWriter.close();
}
3.8 注意
如果xml含有约束条件,那么获取DOM对象则需要把命令空间放在Map集合里,如下
SAXReader reader = new SAXReader();
HashMap<String, String> map = new HashMap<>();
map.put("t", "http://itsource.cn");
reader.getDocumentFactory().setXPathNamespaceURIs(map);
Document dom = reader.read(new File("resources/contacts.xml"));
Node node = dom.selectSingleNode("/t:contacts/t:linkman[1]/t:name");
System.out.println(node.getText()