前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >XML概念定义以及如何定义xml文件编写约束条件java解析xml DTD XML Schema JAXP java xml解析 dom4j 解析 xpath dom sax

XML概念定义以及如何定义xml文件编写约束条件java解析xml DTD XML Schema JAXP java xml解析 dom4j 解析 xpath dom sax

作者头像
noteless
发布2018-09-11 11:06:24
3.1K0
发布2018-09-11 11:06:24
举报
文章被收录于专栏:noteless

本文主要涉及:xml概念描述,xml的约束文件,dtd,xsd文件的定义使用,如何在xml中引用xsd文件,如何使用java解析xml,解析xml方式dom sax,dom4j解析xml文件

XML来源SGML

SGML(SGM)标准通用标记语言

是一种定义电子文档结构和描述其内容的国际标准语言,具有极好的扩展性

是所有电子文档标记语言的起源,早在万维网发明之前“通用标言”就已存在

是1986年国际标准化组织出版发布的一个信息管理方面的国际标准(ISO 8879:1986 信息处理)

简单的理解就是对于数据进行结构化组织呈现,用于描述文档的显示式样或者描述文档中文字的用途

XML概念

可扩展标记语言,是一种用于标记电子文件使其具有结构性的标记语言。

与HTML一样都是标准通用标记语言的子集,

只不过超文本标记语言被设计用来显示数据

XML被设计用来传输和存储数据.

语法上和HTML也是相似的,但HTML中的元素是固定的,而XML的标签是可以由用户自定义的

逻辑上来说SGML是非常适合用于Web项目中的

但是SGML的固有缺点,复杂/庞大/学习成本高等

所以XML这一SGML的子集,应运而生.

W3C在1998年2月发布1.0版本

W3C在2004年2月发布1.1版本,但因为1.1版本不能向下兼容1.0版本

所以现在使用的仍旧是1.0版本

W3school XML在线文档

http://www.w3school.com.cn/xml/index.asp

W3C组织

W3C是万维网联盟(World Wide Web Consortium)英文的缩写

它成立于1994年10月,以开放论坛的方式来促进开发互通技术(包括规格、指南、软件和工具),开发网络的全部潜能。

万维网联盟(W3C)从1994年成立以来,已发布了90多份Web技术规范,领导着Web技术向前发展。

W3C认为自身不是官方组织,因此将它正式发布的规范称为推荐(建议)标准,意思是进一步标准化的建议,

但是由于组织自身的权威性往往成为事实上的标准。


XML用法以及特点

XML在web中主要用途就是存储数据,只要能方便的存储数据,自然可以交换数据.

目前常用用法:

     程序的配置文件(这也是最后大家使用XML最常见的目的);

     数据交换:不同语言之间用来交换数据,因为他是统一的格式

     小型数据库:用来当数据库存储数据。

XML与HTML比较

       HTML的元素都是固定的,而XML可以自定义元素;

       HTML用浏览器来解析执行, XML的解析器通常需要自己来写(因为元素是自定义的);

       HTML只能用来表示网页,而XML可以做的事情很多。

XML和properties(属性文件)比较

       属性文件只能存储平面信息,而XML可以存储结构化信息;

       解析属性文件只需要使用Properties类就可以了,而解析XML文档是很复杂的。

XML总结:

XML是一种灵活的结构化数据存储和传输格式,没有预置的标签(HTML就是预置的固定的,浏览器负责解析)

所以需要自定义标签,

既然是自定义标签 ,自然需要自己去动手解析

也就是说:

在Web项目中,想要使用XML作为程序的一部分

XML三要素

1.语法格式   这个没什么好说的,必须遵守基本的XML规范

2.约束文件

任何的程序都不会是固定不变的,你的解析程序和XML文件也绝对不可能是完全不变的

比如可能你的XML文件需要用户书写,然后程序进行解析

如果用户随意书写,不可能存在什么程序能够保证完全正确的解读用户的输入

所以需要约束,也正是这个约束  让XML的内容的书写,和XML的解析程序达到了解耦的目的

只要引入了约束标准,XML文件的内容就不允许随意书写

只要遵循约束标准,解析程序就承诺一定可以正确的解读数据

3.解析   你自己定义的标签,自然只有你自己才懂得每个数据的含义

一个简单的XML文档格式

目前仍旧使用的是XML 1.0

一个基本的XML 形如:

<?xml version="1.0" encoding="ISO-8859-1"?> <note> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> </note>

XML是一个树形结构,而且必须是一个树形结构  必须有根元素

<bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="WEB"> <title lang="en">Learning XML</title> <author>Erik T. Ray</author> <year>2003</year> <price>39.95</price> </book> </bookstore>

XML-语法

文档声明

元素

属性

注释

CDATA区 、特殊字符

处理指令(PI:Processing Instruction)

文档声明:

在编写XML文档时,需要先使用文档声明来声明XML文档。且必须出现在文档的第一行。

          最简单的语法:<?xml version=“1.0”?>

encoding属性说明文档所使用的字符编码。保存在磁盘上的文件编码要与声明的编码一致。

          如:<?xml version=“1.0” encoding=“GB2312”?>

standalone属性说明文档是否独立,即是否依赖其他文档。

  如:<?xml version=“1.0” standalone=“yes”?>

没有xml文档声明的xml文档,不是格式良好的xml文档

xml文档声明必须从xml文档的1行1列开始  也就是必须第一行顶格写

编码属性应当被指定为文档被保存时所使用的编码

最好的避免错误的建议是

使用支持编码的编辑器

确定编辑器使用的编码

在您的 XML 文档中使用相同的编码属性

XML元素

XML中的每一个标签,就是一个元素

元素指的是从(且包括)开始标签直到(且包括)结束标签的部分

元素可包含其他元素、文本或者两者的混合物。元素也可以拥有属性。

要求:

1.所有元素都必须有关闭标签,省略关闭标签是非法的。声明不是XML的元素,所以第一行的声明,并不需要关闭标签

2.XML 标签对大小写敏感

3.XML 必须正确地嵌套

4.XML 文档必须有且只有一个根元素

命名规则:

1.名称可以含字母、数字以及其他的字符

2.名称不能以数字或者标点符号开始

3.名称不能以字符 “xml”(或者 XML、Xml)开始

4.名称不能包含空格

5.可使用任何名称,没有保留的字词。

命名建议:

名称应该具有描述性,并且在此基础上尽可能简短,可以使用下划线  _ 

避免使用连字符 -   ,比如 a-b   有些可能会仅仅解析到a

不要使用 英文句号  .   

不要使用 英文冒号  :   会被当做命名空间解析

XML属性

一个元素(标签)可以有多个属性

XML的属性是键值对的形式, 

属性由属性名与属性值构成,中间用等号连接  比如  sex="male"

他的属性值必须加引号

单引号和双引号均可使用

如果属性值本身包含双引号,那么有必要使用单引号

到底是使用元素还是属性?

建议是如果可以,尽可能的使用元素,而不是属性

因为:

属性无法包含多重的值(元素可以包含多个)

属性无法描述树的结构(元素则是树结构的一部分)

属性不容易扩展

数据本身设置为元素,数据的数据才去设置为属性

XML注释

注释的语法与 HTML 的语法很相似:

<!-- 这是一个注释 -->

注释不能嵌套

CDATA区 、特殊字符

所有 XML 文档中的文本均会被解析器解析。

只有 CDATA 区段(CDATA section)中的文本会被解析器忽略。

CDATA 部分中的所有内容都会被解析器忽略。 CDATA 部分由 "<![CDATA[" 开始,由 "]]>" 结束

CDATA 部分不能包含字符串 "]]>"。也不允许嵌套的 CDATA 部分。

标记 CDATA 部分结尾的 "]]>" 不能包含空格或折行。

在 XML 中,文档中的空格不会被删除,都会保留

所以,在编写XML文件时,使用换行和缩进等方式来让原文件中的内容清晰可读的“良好”书写习惯在这个地方并不是一件好事

XML 以 LF 存储换行

特殊字符

在 XML 中,一些字符拥有特殊的意义。

如果你把字符 "<" 放在 XML 元素中,会发生错误,这是因为解析器会把它当作新元素的开始

预定义的实体

实体是用于定义引用普通文本或特殊字符的快捷方式的变量。

实体引用是对实体的引用。

实体可在内部或外部进行声明。

&开头    ; 结尾

处理指令

处理指令,简称PI(Processing Instruction)。 了解一下

作用:用来指挥软件如何解析XML文档。

语法:必须以“<?”作为开头,以“?>”作为结尾。与声明是一样

常用处理指令:

XML声明:<?xml version=“1.0” encoding=“GB2312”?>

xml-stylesheet指令:

作用:指示XML文档所使用的CSS样式XSL。

<?xml-stylesheet type="text/css" href="some.css"?>

注:对中文命名的标签元素不起作用

XML-验证约束

验证方式有两种:

DTD   

XML Schema

要理解限制本身的含义,限制是对于XML文档结构的限制

XML中文档的主要内容可以说是  元素和属性

限制也是针对元素和限制来进行的

  • 一个XML文档有哪些元素?
  • 有哪些属性?
  • 哪些属性在哪些元素上?
  • 哪些元素可以包含哪些元素?
  • 被包含的元素可出现的次数是多少?
  • 属性的值可以是多少?
  • .......

大致也就是这些方面的限制

所以如果你想要给你的XML文档编写限制文件,你需要先确定你自己的逻辑规则

也就是上面提到的这几个主要问题

然后查找文档 用对应的方法书写出来即可

不同的限制方式自然有不同的语法,也就有不同的特点

XML Schema 比 DTD 更强大  是DTD的替代者

XML Schema 可针对未来的需求进行扩展

XML Schema 更完善,功能更强大

XML Schema 基于 XML 编写

XML Schema 支持数据类型

XML Schema 支持命名空间

DTD w3c文档

http://www.w3school.com.cn/dtd/dtd_intro.asp

XML Schema  w3c文档

http://www.w3school.com.cn/schema/schema_intro.asp

dtd xsd约束的引用

DTD文件引用

有三种方式

内部

外部(在本地)

公共(也是外部只不过不在本地)

内部直接定义在DOCUTYPE内,格式为:

<!DOCUTYPE 根元素名称[ ]>

外部本地

<!DOCTYPE 根元素名称 SYSTEM "dtd文档路径">

比如

<!DOCTYPE student SYSTEM "test.dtd">

公共DTD也就是网络上的,本质也是外部

<!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD文档的URL" >

比如 mybatis的mapper文件

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

一般都是使用第三方提供的技术框架等,使用XML进行数据配置,使用他们提供的DTD进行约束限制

XML Schema xsd文件引用

XSD文档中是创建元素和属性的地方;

XML文档中是使用元素和属性的地方。

所以在XML文档中需要说明使用了哪些XSD文档。

在 XML 文档中引用 Schema, 引用信息是设置到根元素的开始标签内

<根元素名称  此处为引用信息 > 此处为xml文件的正文内容 </根元素名称>

想要弄清楚引用方式必须了解清楚xsd schema文档的定义格式

每个xsd文件都是一个XML文件

schema是所有文件的根元素

一个 schema 声明往往看上去类似这样

<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3school.com.cn" xmlns="http://www.w3school.com.cn" elementFormDefault="qualified"> ... ... </xs:schema>

其中:

xmlns="http://www.w3school.com.cn"  表示默认的命名空间是"http://www.w3school.com.cn"

xmlns:xs="http://www.w3.org/2001/XMLSchema" 显示 schema 中用到的元素和数据类型来自命名空间 "http://www.w3.org/2001/XMLSchema"。

                             同时它还规定了来自命名空间 "http://www.w3.org/2001/XMLSchema" 的元素和数据类型应该使用前缀 xs:

targetNamespace="http://www.w3school.com.cn"  表示被此 schema 定义的元素  来自命名空间: "http://www.w3school.com.cn"

elementFormDefault="qualified"   任何 XML 实例文档所使用的且在此 schema 中声明过的元素必须被命名空间限定

比如Spring的配置文件

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:task="http://www.springframework.org/schema/task" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">

beans为根元素,整个文档的结构为:

                                           <beans>

</beans>

所有的引用信息设置在 开始标签 <beans> 内

xmlns 与xmlns:xxx 是一样的,只不过是xmlns是默认的命名空间,也就是省略了前缀的元素使用的命名空间

它的值也就是xsd文件中的targetNamespace  的值

还需要设置

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

一旦您拥有了可用的 XML Schema 实例命名空间

您就可以使用 schemaLocation 属性了。

此属性有两个值。第一个值是需要使用的命名空间。第二个值是供命名空间使用的 XML schema 的位置

需要引用xsd文档的大致步骤

1,先确立你的根元素 比如: <beans> </beans> 2.然后选择你的默认的命名空间 xmlns="" 3.默认的只有一个如果你还有更多,你需要设置别名 xmlns:xxx=""  可以设置多个 可能还需要指定位置 4,需要给约束指定位置,指定位置的前提就是先包含XML Schema 实例命名空间: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5.使用xsi:schemaLocation=""   指定具体的位置

到底什么是名称空间?

名称空间是用来处理XML元素或属性的名字冲突问题。你可以理解为Java中的包!包的作用就是用来处理类的名字冲突问题。

无论是在XML中,还是在XSD中,都需要声明名称空间。这与Java中使用import来导包是一个道理。

如果被定义的元素在声明时没有指定目标名称空间,那么就是在无名称空间中,

那么我们在使用这些在无名称空间中的元素时,就不用再去声明名称空间了。

声明名称空间使用xmlns

例如:xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"。

这表示声明了一个名称空间,相当与Java中的import。

但是,Java中的import的含义是在下面使用的类,如果没有给出包名,那么就是import导入的这个类。

而xmlns表示,下面使用xsi为前缀的元素或属性,都是来自http://www.w3.org/2001/XMLSchema-instance名称空间。

也就是说给名称空间起了一个简称  别名 前缀 指定了就必须使用这个

例如在XSD文件中,xmlns:xsd="http://www.w3.org/2001/XMLSchema"就是声明名称空间,

而这个名称空间是W3C的名称空间,无需关联文件就可以直接声明

在XSD文件中所有使用xsd为前面的元素和属性都是来自http://www.w3.org/2001/XMLSchema名称空间。

名称空间命名:一般名称空间都是以公司的URL来命名,即网址!当然也可以给名称空间命名为aa、bb之类的名字,但这可能会导致名称空间的重名问题。

前缀命名:前缀的命名没有什么要求,但一般对http://www.w3.org/2001/XMLSchema名称空间的前缀都是使用xs或xsd。

http://www.w3.org/2001/XMLSchema-instance的前缀使用xsi。

默认名称空间

所谓默认名称空间就是在声明名称空间时,不指定前缀,也可以理解为前缀为空字符串的意思。

这样定义元素时,如果没有指定前缀的元素都是在使用默认名称空间中的元素。

xmlns=”http://www.w3.org”

当在文档中使用<xxx>时,那么<xxx>元素就是http://www.w3.org名称空间中声明的元素。

注意:没有指定前缀的属性不表示在默认名称空间中,而是表示没有名称空间。也就是说,默认名称空间不会涉及到属性,只对元素有效


XML解析

DOM:Document Object Model,文档对象模型。这种方式是W3C推荐的处理XML的一种方式。

SAX:Simple API for XML。这种方式不是官方标准,属于开源社区XML-DEV,属于事实上的标准

这是两种操作逻辑,是一种规范描述,是一组标准接口

并不是针对java语言解析dom的技术

DOM和SAX只是定义了一些接口,以及某些接口的缺省实现,而这个缺省实现只是用空方法来实现接口。

一个应用程序如果需要DOM或SAX来访问XML文档,还需要一个实现了DOM或SAX的解析器,

也就是说这个解析器需要实现DOM或SAX中定义的接口以能够提供DOM或SAX中定义的功能。

DOM解析原理

DOM要求解析器把整个XML文档装载到一个Document对象中。

Document对象包含文档元素,即根元素,根元素包含N多个子元素…

一个XML文档解析后对应一个Document对象,

这说明使用DOM解析XML文档方便使用,因为元素与元素之间还保存着结构关系。

优先:使用DOM,XML文档的结构在内存中依然清晰。元素与元素之间的关系保留了下来!

缺点:如果XML文档过大,那么把整个XML文档装载进内存,可能会出现内存溢出的现象!

SAX解析原理

DOM会一行一行的读取XML文档,最终会把XML文档所有数据存放到Document对象中。

SAX也是一行一行的读取XML文档,但是当XML文档读取结束后,SAX不会保存任何数据,同时整个解析XML文档的工作也就结束了。

但是,SAX在读取一行XML文档数据后,就会给感兴趣的用户一个通知!这是一种回调的形式

例如当SAX读取到一个元素的开始时,会通知用户当前解析到一个元素的开始标签。

而用户可以在整个解析的过程中完成自己的业务逻辑,当SAX解析结束,不会保存任何XML文档的数据。

优先:使用SAX,不会占用大量内存来保存XML文档数据,效率也高。

缺点:当解析到一个元素时,上一个元素的信息已经丢弃,也就是说没有保存元素与元素之间的结构关系,这也大大限制了SAX的使用范围。

如果只是想查询XML文档中的数据,那么使用SAX是最佳选择!

JAXP

JAXP(Java API for XMLProcessing,意为XML处理的Java API)是Java XML程序设计的应用程序接口之一

JAXP是sun提供的 用于隐藏底层解析器的实现

java要求XML解析器去实现JAXP提供的接口,这样可以让用户使用解析器时不依赖特定的XML解析器

JAXP本身不是解析器

也不是解析方式(DOM或SAX),它只是让用户在使用DOM或SAX解析器时不依赖特点的解析器。

所以可以说是JAXP是java提供的统一的解析XML的接口规范

你不在需要关注任何的具体的XML解析器的细节

只需要使用JAXP接口规范定义的API即可

JAXP DOM解析

jdk中  javax.xml.parsers包下,四个类:

其中DOM方式:

DocumentBuilder   解析器类

DocumentBuilderFactory 解析器工厂

DocumentBuilder 抽象类,可以使用DocumentBuilderFactory.newDocumentBuilder()  获得

DocumentBuilderFactory 抽象类,可以使用他的newInstance()方法获取实例

parse方法返回Document接口,父接口是Node

示例:

代码语言:javascript
复制
 1 import javax.xml.parsers.DocumentBuilder;
 2 import javax.xml.parsers.DocumentBuilderFactory;
 3 import javax.xml.transform.Transformer;
 4 import javax.xml.transform.TransformerFactory;
 5 import javax.xml.transform.dom.DOMSource;
 6 import javax.xml.transform.stream.StreamResult;
 7 
 8 import org.w3c.dom.Document;
 9 import org.w3c.dom.Element;
10 import org.w3c.dom.Node;
11 import org.w3c.dom.NodeList;
12 import org.w3c.dom.Text;
13 
14 public class DomParseTest {
15 
16 public static void main(String[] args) throws Exception {
17 
18  
19 
20 //创建解析器工厂
21 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
22 //使用工厂创建解析器
23 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
24 //使用解析器解析XML文件得到Document对象
25 Document document = documentBuilder.parse("src/dom/test.xml");
26 //根据标签名获取 NodeList是一个集合 集合中的元素时Node 使用item() 获取元素
27 NodeList nodeList = document.getElementsByTagName("name");
28 for(int i=0;i<nodeList.getLength();i++) {
29 Node node = nodeList.item(i);
30 //得到标签里面的内容
31 System.out.println(node.getTextContent());
32 }
33 
34 //给第一个学生增加一个性别属性
35 //查找第一个学生
36 Node firstStudent = document.getElementsByTagName("student").item(0);
37 //创建性别标签
38 Element sexElement = document.createElement("sex");
39 //创建性别标签对应的文本
40 Text sexElementText= document.createTextNode("男");
41 //文本添加到标签上
42 sexElement.appendChild(sexElementText);
43 //标签添加到第一个学生节点上
44 firstStudent.appendChild(sexElement);
45 
46 //回写数据
47 //需要使用transformer 抽象类 由工厂创建,工厂也是抽象类由newInstance()方法创建
48 TransformerFactory transformerFactory = TransformerFactory.newInstance();
49 Transformer transformer = transformerFactory.newTransformer();
50 //拥有tranform()方法进行传输数据
51 //transform(Source xmlSource, Result outputTarget)
52 //Source的实现类DOMSource有构造方法
53 //Result接口有实现类StreamResult
54 transformer.transform(new DOMSource(document), new StreamResult("src/dom/test.xml"));
55 
56 
57 }
58 
59 }

<?xml version="1.0" encoding="UTF-8" standalone="no"?><students>         <student>                 <name>张三</name>                 <age>18</age>         </student>         <student>                 <name>李四</name>                 <age>28</age>         </student> </students>

虽然方法有很多,但是本质很简单,解析器,解析器工厂

解析器解析出来文档结构

既然是DOM树,自然都是节点

Document Element   Text   Attr 也都是节点 Node 类型的

NodeList 是包含Node 的集合 可以使用item方法获取节点 所以说一旦解析出来文档

一切皆是Node 针对于操作方法都在这个体系内了

再详细一点的说就是:

无论使用什么DOM解析器,最终用户都需要获取到Document对象,一个Document对象对应整个XML文档。也可以这样说,Document对象就是XML文档在内存中的表示形式。

在DOM中提供了很多接口,用来描述XML文档中的组成部分。

其中包括:文档(Document)、元素(Element)、属性(Attr)、文本(Text)、注释(Comment)、CDATA段(CDATASection)等等。

无论是哪种XML文档组成部分,都是节点(Node)的子接口。

Node方法介绍
Node基本方法:

l String getNodeName():获取当前节点的名字。如果当前节点是Element,那么返回元素名称。如果当前节点是Text那么返回#text。如果当前节点是Document那么返回#document;

l String getNodeValue():获取当前节点的值。只有文本节点有值,其它节点的值都为null;

l String getTextContext():获取当前节点的文本字符串。如果当前节点为Text,那么获取节点内容。如果当前节点为Element,那么获取元素中所有Text子节点的内容。例如当前节点为:<name>zhangSan</name>,那么本方法返回zhangSan。如果当前节点为:<student><name>zhangSan</name><age>23</age><sex>male</sex></student>,那么本方法返回zhangSan23male。

l short getNodeType():获取当前节点的类型。Node中有很多short类型的常量,可以通过与这些常量的比较来判断当前节点的类型。if(node.getNodeType() == Node.ELEMENT_NODE);

Node获取子节点和父节点方法,只有Document和Element才能使用这些方法:

l NodeList getChildNodes():获取当前节点的所有子节点。NodeList表示节点列表,它有两个方法:

l int getLength():获取集合长度;

l Node item(int index):获取指定下标的节点。

l Node getFirstNode():获取当前节点的第一个子节点;

l Node getLastNode():获取当前节点的最后一个子节点;

l Node getParentNode():获取当前节点的父节点。注意Document的父节点为null。

Node获取弟兄节点的方法,只有Element才能使用这些方法:

l Node getNextSibling():获取当前节点的下一个兄弟节点;

l Node getPreviousSibling():获取当前节点的上一个兄弟节点。

Node添加、替换、删除子节点方法:

l Node appendChild(Node newChild):把参数节点newChild添加到当前节点的子节点列表的末尾处。返回值为被添加的子节点newChild对象,方便使用链式操作。如果newChild在添加之前已经在文档中存在,那么就是修改节点的位置了;

l Node insertBefore(Node newChild, Node refNode):把参数节点newChild添加到当前节点的子节点refNode之前。返回值为被添加的子节点newChild对象,方便使用链式操作。如果refNode为null,那么本方法与appendNode()方法功能相同。如果newChild节点在添加之前已经在文档中存在,那么就是修改节点的位置了。

l Node removeNode(Node oldChild):从当前节点中移除子元素oldChild。返回值为被添加的子节点oldChild对象,方便使用链式操作。

l Node replaceNode(Node newChild, Node oldChild):将当前节点的子节点oldChild替换为newChild。

Node获取属性集合方法,只有Element可以使用:

l NamedNodeMap getAttributes():返回当前节点的属性集合。NamedNodeMap表示属性的集合,方法如下:

int getLength():获取集合中属性的个数;

Node item(int index):获取指定下标位置上的属性节点;

Node getNamedItem(String name):获取指定名字的属性节点;

Node removeNamedItem(String name):移除指定名字的属性节点,返回值为移除的属性节点;

Node setNamedItem(Node arg):添加一个属性节点,返回值为添加的属性节点。

Node的判断方法

l boolean hasChildNodes():判断当前节点是否有子节点;

l boolean hasAttribute():判断当前节点是否有属性。

Docment方法介绍

创建节点方法:

l Attr createAttribute(String name):创建属性节点;

l CDATASection createCDATASection(String data):创建CDATA段节点;

l Comment createComment(String data):创建注释;

l Element createElement(String tagName):创建元素节点;

l Text createTextNode(String data):创建文本节点;

获取子元素方法:

l Element getElementById(String elementId):通过元素的ID属性获取元素节点,如果没有DTD指定属性类型为ID,那么这个方法将返回null;

| NodeList getElementsByTagName(String tagName):获取指定元素名称的所有元素;

l Element getDocumentElement():获取文档元素,即获取根元素。

文档声明相关方法:

l String getXmlVersion():获取文档声明的version属性值;

l String getXmlEncoding():获取文档声明的encoding属性值;

l String getXmlStandalone():获取文档声明的standalone属性值;

l void setXmlVersion():设置文档声明version属性值;

l void setXmlStandalone():设置文档声明standalone属性值。

Element方法介绍

获取方法:

l NodeList getElementsByTagName(String tagName):获取当前元素的指定元素名称的所有子元素;

l String getTagName():获取当前元素的元素名。调用元素节点的getNodeName()也是返回名;

属性相关方法:

l String getAttribute(String name):获取当前元素指定属性名的属性值;

l Attr getAttributeNode(String name):获取当前元素指定属性名的属性节点;

l boolean hasAttribute(String name):判断当前元素是否有指定属性;

l void removeAttribute(String name):移除当前元素的指定属性;

l void removeAttributeNode(Attr attr):移除当前元素的指定属性;

l void setAttribute(String name, String value):为当前元素添加或修改属性;

l Attr setAttributeNode(Attr attr):为当前元素添加或修改属性,返回值为添加的属性;

Attr方法介绍

l String getName():获取当前属性节点的属性名;

l String getValue():获取当前属性节点的属性值;

l void setValue(String value):设置当前属性节点的属性值;

l boolean isId():判断当前属性节点是否为ID类型属性。

JAXP SAX解析

SAXParser 解析器类

SAXParserFactory 解析器工厂

SAX是事件驱动型XML解析的一个标准接口

对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数

我们需要做的就是实现这些回调的方法体

示例:

代码语言:javascript
复制
public static void SaxParse() throws Exception {

                //创建解析器工厂
                SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
                //创建解析器
                SAXParser saxParser = saxParserFactory.newSAXParser();
                //执行parse方法 此方法依赖DefaultHandler,所以需要自定义类实现DefaultHandler
                //其中qName 是标签的名称
                saxParser.parse("src/dom/test.xml", new DefaultHandler() {

                        @Override
                        public void startElement(String uri, String localName, String qName, Attributes attributes)
                                        throws SAXException {
                                System.out.println("<"+qName+">");
                        }

                        @Override
                        public void endElement(String uri, String localName, String qName) throws SAXException {
                                System.out.println("<"+qName+"/>");

                        }

                        @Override
                        public void characters(char[] ch, int start, int length) throws SAXException {
                                System.out.print(new String(ch,start,length));
                        }


                });
        }

DefaultHandler中还有很多的其他方法

使用DOM解析主要就是获取文档后对于所有的节点进行操作

使用SAX解析主要就是根据各个事件发生时,进行所需要的响应

如果想要对文档进行复杂的操作设置更多的需要查询Node下相关的实现类  Document Text 等

如果想要对文档进行复杂的筛选查询,那么需要精心的利用DefaultHandler处理各个事件

注意:既然说JAXP是一个接口规范,为什么可以直接使用其来进行解析?

上面我们已经提到了工厂类都是抽象类,并不是自己实现的或者创建的,调用的newInstance创建的,他其实使用的是java提供给我们的默认实现的解析器工作的

JAXP还是接口规范,并不是一组实现API

JDOM和DOM4J

这是两种第三方的解析工具 仅仅用于java

JDOM与DOM4J相比,DOM4J完胜!!!所以,我们应该在今后的开发中,把DOM4J视为首选。

DOM4J也是Hibernate使用的解析XML的方式

DOM4J查找解析器的过程

DOM4J首先会去通过JAXP的查找方法去查找解析器,如果找到解析器,那么就使用之;

否则会使用自己的默认解析器Aelfred2。

https://github.com/dom4j/dom4j/wiki/FAQ  中有关于解析器的说明

DOM4J对DOM和SAX都提供了支持

可以把DOM解析后的Document对象转换成DOM4J的Document对象,当然了可以把DOM4J的Document对象转换成DOM的Document对象。

DOM4J使用SAX解析器把XML文档加载到内存,生成DOM对象。当然也支持事件驱动的方式来解析XML文档。

在DOM4J中,也有Node、Document、Element等接口,结构上与DOM中的接口比较相似。

但还是有很多的区别:

在DOM4J中,所有XML组成部分都是一个Node,

其中Branch表示可以包含子节点的节点,

例如Document和Element都是可以有子节点的,它们都是Branch的子接口。

Attribute是属性节点,CharacterData是文本节点,

文本节点有三个子接口,分别是CDATA、Text、Comment。

dom4J 官网 https://dom4j.github.io/

刚才提到的工作原理

DOM4J使用SAX解析器把XML文档加载到内存,生成DOM对象。当然也支持事件驱动的方式来解析XML文档。

这句话是重点,他两种解析方式都可以,而且,他是使用的SAX解析方式 创建了一棵DOM4J树,此树中的对象  可以转换成DOM树中的对象

dom4j 2.1.1 API

https://dom4j.github.io/javadoc/2.1.1/overview-summary.html

第三方的工具使用必然需要查看他的介绍方法

基本的使用在官网上已经有了很清晰的介绍 

官网 https://dom4j.github.io/

获取指定元素标签的内容

代码语言:javascript
复制
        
//查询元素
public static void dom4jParseSelectNames() throws Exception {
                //1.导入包  import org.dom4j.io.SAXReader;
                //2.创建解析器
                SAXReader saxReader = new SAXReader();
                //3.使用解析器解析文档
                Document document = saxReader.read("src/dom/test.xml");
                //4.得到根节点
                Element root = document.getRootElement();

                //5.得到指定元素的列表
                List<Element> list = root.elements("student");
                //6.遍历list
                for (Element element : list) {
                        //element是每一个student元素 得到student下面的name元素
                        Element name = element.element("name");
                        //得到name里面的值
                        String s = name.getText();
                        System.out.println(s);
                }


        }
}
代码语言:javascript
复制
//增加一个元素
public static void dom4jParseAdd() throws Exception {
                //1.导入包  import org.dom4j.io.SAXReader;
                //2.创建解析器
                SAXReader saxReader = new SAXReader();
                //3.使用解析器解析文档
                Document document = saxReader.read("src/dom/test.xml");
                //4.得到根节点
                Element root = document.getRootElement();

                //5.得到第一个student元素
                Element studentElement = root.element("student");
                //6.在student下面直接添加元素
                Element sexElement = studentElement.addElement("sex");
                //7.在sex下面添加文本
                sexElement.setText("男");

                //8.回写数据
                OutputFormat format = OutputFormat.createPrettyPrint();
                XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/dom/test.xml"), format);
                xmlWriter.write(document);
                xmlWriter.close();

        }

使用Dom4J格式都没有变乱

XPATH

什么是 XPath?

XPath 使用路径表达式在 XML 文档中进行导航

XPath 包含一个标准函数库

XPath 是 XSLT 中的主要元素

XPath 是一个 W3C 标准

http://www.w3school.com.cn/xpath/index.asp

XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。

XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力。

起初 XPath 的提出的初衷是将其作为一个通用的、介于XPointer与XSL间的语法模型。但是 XPath 很快的被开发者采用来当作小型查询语言。

就按照他的名字XML Path Language 理解就可以完全掌握这个概念

在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档节点(或称为根节点)。

类型都是节点类型的

其中直接值也就是常量 ,比如xml中的<year>2018</year> 2018就是基本值 原子值

节点之间的相互关系有 :

父   每个元素以及属性都有一个父。

子   元素节点可有零个、一个或多个子。

同胞   拥有相同的父的节点

先辈  某节点的父、父的父,等等

后代    某个节点的子,子的子,等等。

DOM4J对XPath的支持

在DOM4J中,Node接口中的三个方法最为常用: 

        List selectNodes(String xpathExpression):在当前节点中查找满足XPath表达式的所有子节点;

        Node selectSingleNode(String xpathExpression):在当前节点中查找满足XPath表达式的第一个子节点;

        String valueOf(String xpathExpression):在当前节点中查找满足XPath表达式的第一个子节点的文本内容;

语法格式可以根据w3school中的语法形式进行选择

http://www.w3school.com.cn/xpath/xpath_syntax.asp

想要在DOM4J中解析XPATH还需要另外一个包  Jaxen

可以去中央仓库下载 或者随便搜索一下  jaxen-1.1-beta-6.jar

否则就会报错

Jaxen是一个用Java编写的XPath引擎,用于处理各种基于XML的对象模型,如DOM,dom4j和JDOM以及Java Bean。

代码语言:javascript
复制
public static void dom4jParseXpath() throws Exception {
                //1.导入包  import org.dom4j.io.SAXReader;
                //2.创建解析器
                SAXReader saxReader = new SAXReader();
                //3.使用解析器解析文档
                Document document = saxReader.read("src/dom/test.xml");
                //4.得到根节点
                List<Node> nodes = document.selectNodes("//name");
                //5.遍历list
                for (Node node : nodes) {
                        //得到name里面的值
                        String s = node.getText();
                        System.out.println(s);
                }

                System.out.println("---------");


                List<Node> nodess = document.selectNodes("//student");
                //5.遍历list
                for (Node node : nodess) {

                        //得到name里面的值
                        String s = node.getStringValue();
                        System.out.println(s);
                }
        }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-08-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • XML来源SGML
  • XML概念
  • W3C组织
  • XML用法以及特点
    • 目前常用用法:
      • XML与HTML比较
        • XML和properties(属性文件)比较
          • XML总结:
          • XML三要素
            • 一个简单的XML文档格式
            • XML-语法
            • 文档声明:
            • XML元素
            • XML属性
            • XML注释
              • CDATA区 、特殊字符
              • 处理指令
              • XML-验证约束
              • DTD文件引用
              • XML Schema xsd文件引用
                • 到底什么是名称空间?
                  • 默认名称空间
                  • XML解析
                    • DOM解析原理
                      • SAX解析原理
                      • JAXP
                      • JAXP DOM解析
                        • Node方法介绍
                          • Node基本方法:
                            • Element方法介绍
                              • Attr方法介绍
                              • JAXP SAX解析
                              • JDOM和DOM4J
                                • DOM4J查找解析器的过程
                                • XPATH
                                  • 什么是 XPath?
                                  • DOM4J对XPath的支持
                                  相关产品与服务
                                  对象存储
                                  对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                                  领券
                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档