XML
XML入门
一、xml的简介
1、extensible Markup Language:可扩展标记型语言
-
标记型语言: html是标记型语言
- 也是使用标签来操作
-
可扩展:
- html里面的标签是固定,每个标签都有特定的含义
- 标签可以自己定义,可以写中文的标签
、<猫>/<猫>
- html里面的标签是固定,每个标签都有特定的含义
2、xml用途
-
html是用于显示数据,xml也可以显示数据(不是主要功能)
-
xml主要功能,为了存储数据
3、xml是w3c组织发布的技术
4、xml有两个版本1.0和1.1
- 使用都是1.0版本:(1.1版本不能向下兼容)
二、xml的应用
1、经常用在文件配置
- 比如现在连接数据库肯定知道数据库的用户名和密码,数据名称
- 如果修改数据库的信息,不需要修改源代码,只要修改配置文件就可以了
2、不同的系统之间传输数据
-
qq之间数据的传输
-

-

3、用来表示生活中有关系的数据


三、xml的语法
(1) xml的文档声明(***)
-
创建一个文件后缀名是.xml
-
如果写xml,第一步必须要有一个文档声明(写了文档声明之后,表示写xml文件的内容)
-
<?xml version="1.0" encoding="gbk"?> -
文档声明必须写在第一行第一列
-
-
属性
-
version: xml的版本1.0(使用)1.1
-
encoding: xml编码有 gbk utf-8 iso8859-1(不包含中文)
-
standalone:是否需要依赖其他文件 yes/no
-
-
中文乱码问题解决
- 原因:xml文件保存时不是以utf-8的编码保存,而是以gbk编码格式保存到本地硬盘。
- 解决方法:保存文件以utf-8格式保存即可。

-
xml文件示例
<?xml version="1.0" encoding="utf-8" ?> <person> <name>张三</name> <age>20</age> </person>
(2)定义元素(标签)(***)
-
标签定义
-
标签定义有开始必须要有结束:
<person></person> -
标签没有内容,可以在标签内结束:
<aa/>
-
-
标签可以嵌套,必须要合理嵌套
-
合理嵌套
<aa><bb></bb></aa> -
不合理嵌套
:这种方式是不正确的
-
-
一个xml中,只能有一个根标签,其他标签都是这个标签下面的标签在xml中把空格和换行都当成内容来解析
-
下间这两段代码含义是不一样的
<aa>1111111</aa>
-
<aa> 111111111 </aa>
-
-
xml标签可以是中文
-
xml中标签的名称规则
-
(1)xml代码区分大小马
<p>和<P>:这两个标签是不一样 -
(2) xml的标签不能以数字和下划线()开头
<2a>和<aa>:这样是不正确的 -
(3)xml的标签不能以xml、XML、Xml等开头
<xmla> <XmlB> <XMLC>:这些都是不正确的 -
(4) xml的标签不能包含空格和冒号
<a b> <b:c> :这些是不正确的
-
(3)定义属性(***)
-
html是标记型文档,可以有属性
-
xml也是标记型文档,可以有属性
-
<person id1="aaa" id2="bbb"></person>
-
-
属性定义的要求
-
(1)一个标签上可以有多个属性
<person id1="aaa" id2="bbb"></person> -
(2)属性名称不能相同
<person id1="aaa" id1="bbb"></person>:这个是不正确,不能有两个id1 -
(3)属性名称和属性值之间使用= ,属性值使用引号包起来(可以是单引号,也可以是双引号)
-
(4) xml属性的名称规范和元素(标签)的名称规范一致
-
(4)注释(***)
-
写法
-
注意的地方
-
注释不能嵌套
<!--<!-- -->-->:这是不正确的
-
-
注释也不能放到第一行,第一行第一列必须放文档声明
(5)特殊字符(***)
-
如果想要在xml中现在a<b ,不能正常显示,因为把<当做标签如果就想要显示,需要对特殊字符<进行转义

例如:
<a>a<b</a> 代表了a<b
(6)xml的CDATA区(了解)
-
可以解决多个字符都需要转义的操作如 if(a<b && b<c && d>f) {}把这些内容放到CDATA区里面,不需要转义了
-
把特殊字符,当做文本内容,而不是标签
-
写法
<![CDATA[内容]]>-代码 <![CDATA[if (a<b & & b<c && d>f){}]]>
(7)xml的PI指令(处理指令)
- 作用:用来指挥软件如何解析XML文档。
- 语法:必须以“”作为结尾。
- 常用处理指令:
- xml声明:
- xml-stylesheet指令:
- 作用:指示XML文档所使用的CSS择式xSL。
- 注:对中文命名的标签元素不起作用
总结
- 所有XML元素都须有关闭标签
- XML标签对大小写敏感
- XML必须正确地嵌套顺序
- XML文档必须有根元素(只有一个)
- XML的属性值须加引号
- 特殊字符必须转义---CDATA
- XML中的空格、回车换行会解析时被保留
四、xml的约束
为什么需要约束?
比如现在定义一个person的xml文件,只想要这个文件里面保存人的信息,比如name age等,但是如果在xml文件中写了一个标签<猫>,发现可以正常显示,因为符合语法规范。但是猫肯定不是人的信息,xml的标签是自定义的,需要技术来规定xml中只能出现的元素,这个时候需要约束。
xml的约束的技术:DTD约束和Schema约束
五、DTD
1、DTD的快速入门
-
步骤:
-
创建一个文件后缀名.dtd
-
(1)看xml中有多少个元素,有几个元素,在dtd文件中写几个<!ELEMEN
-
(2)判断元素是简单元素还是复杂元素
-
复杂元素:有子元素的元素
-
<!ELEMENT 元素名称 (子元素)> <!ELEMENT person (name,age)>
-
-
简单元素:没有子元素
-
<!ELEMENT 元素名称 (#PCDATA)> <!ELEMENT name (#PCDATA)>
-
-
-
(3)需要在xml文件中引入dtd文件
<!DOCTYPE 根元素名称 SYSTEM "dtd文件的路径"> 放在XML文件的第二行最好 -
打开xml文件使用浏览器打开的,浏览器只负责校验xml的语法,不负责校验约束
-
如果想要校验xml的约束,需要使用工具(myeclipse工具)
- 打开myeclipse开发工具
- 仓建一个java project项目day05
- 在day05的src目录下面创建一个xml文件和一个dtd文件
- 当xml中引入dtd文件之后,比如只能出现name,age,多写了一个a,会提示出错
2、DTD的三种引入方式
(1)引入外部的dtd文件
<!DOCTYPE 根元素名称 SYSTEM "dtd路径">
(2)使用内部的dtd文件(即直接写在xml文件内)
<!DOCTYPE根元素名称[
<!ELEMENT person (name,age)>
<!ELEMENT name (#PCDATA)>
<!ELEMENTage (#PCDATA)>
]>
(3)使用外部的dtd文件(网络上的dtd文件)
<!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD文档的URL">
后面学到框架struts2使用配置文件使用外部的dtd文件
<!DOCTYPE struts PUBLIc "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
3、DTD定义元素
-
语法:
<!ELEMENT 元素名 约束> -
简单元素:没有子元素的元素
<!ELEMENT name (#PCDATA)>-
(#PCDATA):约束name是字符串类型
-
EMPTY :元素为空(没有内容)
<sex></sex> <!ELEMENT sex (#EMPTY)> -
ANY:元素可以是任意内容
-
-
复杂元素:
<!ELEMENT person (name,age,sex,school)>- 子元素只能出现一个
<!ELEMENT 元素名称 (子元素)>-
表示子元素出现的次数
+:表示一次或者多次
?:表示零次或者一次
*:表示零次或者多次
使用方法:
<!ELEMENT person (name+,age?,sex*,school)> -
子元素直接使用逗号进行隔开,
- 表示子元素出现的项序
-
子元素直接使用 “|” 隔开
-
表示元素只能出现其中的任意一个
<!ELEMENT person (男|女)>
-
4、DTD定义属性
-
语法:
<!ATTLIST 元素名称 属性名称 属性类型 属性的约束 > -
属性值类型:
-
CDATA:表示属性的取值为普通的文本字符串
<!ATTLIST birthday ID1 CDATA #REQUIRED > -
ENUMERATED (DTD没有此关键字):表示枚举,只能从举列表中任选其一,如(鸡肉|牛肉猪肉|鱼肉)
<!ATTLIST age ID2 (AA|BB|CC) #REQUIRED > -
ID表示属性的取值不能重复,属性的值只能由字母,下划线开始,不能出现空白字符
<!ATTLIST name ID3 ID #REQUIRED >
-
-
属性约束设置说明
-
REQUIRED:表示该属性必须出现一次
-
MPLIED:表示该属性可有可无
-
FIXED:表示属性的取值为一个固定值。语法:
#FIXED "固定值" -
直接值:表示属性的取值为该默认值
-
-
定义属性源码示例
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE person[ <!ELEMENT person (name+,age?,sex*,school,birthday)> <!ELEMENT name (#PCDATA)> <!ATTLIST name ID3 ID #REQUIRED > <!ELEMENT age (#PCDATA)> <!ATTLIST age ID2 (AA|BB|CC) #REQUIRED > <!ELEMENT sex (#PCDATA)> <!ATTLIST sex ID4 CDATA #FIXED "ABC" > <!ELEMENT school (#PCDATA)> <!ATTLIST school ID5 CDATA "WWW" > <!ELEMENT birthday (#PCDATA)> <!ATTLIST birthday ID1 CDATA #REQUIRED > ]> <person> <name ID3="AA2">张三</name> <age ID2="AA">20</age> <sex ID4="ABC">222</sex> <school ID5="TTT">111</school> <birthday ID1="SSS">2022</birthday> </person>
5、实体的定义
-
语法:
<!ENTITY 实体名称 "实体的值"> <!ENTITY TEST "HAHAHEHE"> -
使用实体方法:&实体名称; 比如&TEST;
<!ENTITY TEST "HELLOWORLD"> <name ID3="BB">&TEST;</name> -
注意:定义实体需要写在内部dtd里面,如果写在外部的dtd里面,有某些浏览器下,内容得不到
六、xml解析之JAXP(SUN公司提供的API)
1、XML解析方式简介(最重要的内容)
-
xml是标记型文档
-
js使用dom解析标记型文档
- 根据html的层级结构,在内存中分配一个树形结构,把html的标签,属性和文本都封装成对象
- document对象、element对象、属性对象、文本对象、Node节点对象
-
xml的解析方式(技术): dom方式和sax方式
-
画图分析使用dom和sax解析xml过程

-
dom解析和sax解析区别:
- dom方式解析:
- 根据xml的层级结构在内存中分配一个树形结构,把xml的标签,属性和文本都封装成对象
- 缺点:如果文件过大,造成内存溢出
- 优点:很方便实现增删改操作
- sax方式解析
- 采用事件驱动,边读边解析
从上到下,一行一行的解析,解析到某一个对象,
返回对象名称 - 缺点:不能实现增删改操作
- 优点:如果文件过大,不会造成内存溢出,方便实现查询操作
- 采用事件驱动,边读边解析
- dom方式解析:
-
2、JAXP的API
想要解析xml,首先需要解析器
-
不同的公司和组织提供了针对dom和sax方式的解析器,通过api方式提供
-
sun公司提供了针对dom和sax解析器 jaxp
-
dom4组织,针对dom和sax解析器 dom4j(实际开发中)
-
jdom组织,针对dom和sax解析器 jdom
-
-
Jaxp是javase的一部分
-
Jaxp解析器在jdk的javax. xml.parsers包里面
-
四个类:分别是针对dom和sax解析使用的类
-
dom类
-
DocumentBuilder:解析器类
这个类是一个抽象类,不能new
此类的实例可以从 DocumentBuilderFactory.newDocumentBuilder()方法获取
- 一个方法,可以解析xml parse ("xml路径")返回是 Document整个文档
- 返回的document是一个接口,父节点是Node,如果在document里面找不到想要的方法,到Node里面去找
- 在document里面方法
- getElementsByTagName(string tagname)--这个方法可以得到标签
- 返回集合NodeList
- createElement (string tagName)--创创建标签
- createTextNode (string data)--创建文本
- appendchild (Node newchild)--把文本添加到标签下面
- removechild (Node oldchild)--删除节点
- getParentNode ()--获取父节点
- getTextContent()--获取标签里的内容;
- getElementsByTagName(string tagname)--这个方法可以得到标签
- NodeList
- getLength()--得到集合的长度
- item (int index)--下标取到具体的值
for (int i=0;i<list.getLength () ;i++){
list.item (i)
}
-
DocumentBuilderFactory:解析器工厂
这个类也是一个抽象类,不能new
newInstance()获取 DocumentBuilderFactory的实例。
-
-
sax类
- SAXParser:解析器类
- SAXParserFactory:解析器工厂
-
3、使用jaxp实现查询操作
-
查询xml中所有的name元素的值
-
步骤
-
查询所有name元素的值
-
1、创建解析器工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); -
2、根据解析器工厂创建解析器
DocumentBuilder builder = builderFactory.newDocumentBuilder(); -
3、解析xml返回document
Document document = builder.parse("src/person.xml"); -
4、得到所有的name元素
NodeList nameList = document.getElementsByTagName("name"); -
5、返回集合,遍历集合,得到每一个name元素
for (int i = 0; i < nameList.getLength(); i++) { Node name1 = list.item(i); // 得到每一个name元素 // 得到name元素里的每一个值 String s = name1.getTextContent(); System.out.println(s); }
-
-
主程序代码
import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * 实现jaxp查询操作xml */ public class TestJaxp { public static void main(String[] args) throws Exception { // 查询所有的 name 元素的值 /** * 1.创建解析器工厂 * 2.根据解析器工厂创建解析器 * 3.解析xml返回Doucment对象 * 4.得到所有的name元素的 * 5.返回集合,遍历集合,得到每一个name元素 */ // 创建解析器工厂 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); // 创建解析器 DocumentBuilder builder = builderFactory.newDocumentBuilder(); // 解析xml返回document对象 Document document = builder.parse("src/person.xml"); // 得到name元素 NodeList nameList = document.getElementsByTagName("name"); // 遍历集合 for (int i = 0; i < nameList.getLength(); i++) { Node name1 = nameList.item(i); // 得到每一个name元素 // 得到name元素里的每一个值 String s = name1.getTextContent(); System.out.println(s); } } }
4、使用jaxp查询某一个节点里的值
-
查询xml中第一个name元素的值
-
步骤
- 1、创建解析器工厂
- 2、根据解析器工厂创建解析器
- 3、解析xm1,返回document
- 4、得到所有name元素
- 5、使用返回集合,里面方法item,下标获取具体的元素
- NodeList.item(下标):集合下标从0开始
- 6、得到具体的值,使用getTextContent方法
-
主程序代码
public static void selectSin() throws Exception{ /** * - 1、创建解析器工厂 * - 2、根据解析器工厂创建解析器 * - 3、解析xm1,返回document * - 4、得到所有name元素 * - 5、使用返回集合,里面方法item,下标获取具体的元素 * - NodeList.item(下标):集合下标从0开始 * - 6、得到具体的值,使用getTextContent方法 */ // 创建解析器工厂 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); // 根据解析器工厂创建解析器 DocumentBuilder builder = builderFactory.newDocumentBuilder(); // 解析xm1,返回document Document document = builder.parse("src/person.xml"); // 使用返回集合,里面方法item,下标获取具体的元素 NodeList nameList = document.getElementsByTagName("name"); // 使用下标得到第一个元素 Node name = nameList.item(0); String s = name.getTextContent(); System.out.println(s); }
5、使用jaxp添加节点
-
在第一个p1下面(末尾)添加
女 -
步骤
- 1、创建解析器工厂
- 2、根据解析器工厂创建解析器
- 3、解析xml,返回document
- 4、得到第一个p1
- 得到所有p1,使用item方法下标得到
- 5、创建sex标签--createElement
- 6、创建文本--createTextNode
- 7、把文本添加到sex下面--appendchild
- 8、把sex添加到第一个p1下面--appendchild
- 9、回写xml,需要使用流回写
-
主程序代码
public static void addSex() throws Exception{ /** * - 1、创建解析器工厂 * - 2、根据解析器工厂创建解析器 * - 3、解析xml,返回document * - 4、得到所有p1,使用item方法下标得到 * - 得到第一个 p1 * - 5、创建sex标签--createElement * - 6、创建文本--createTextNode * - 7、把文本添加到sex下面--appendchild * - 8、把sex添加到第一个p1下面--appendchild * - 9、回写xml,需要使用流回写 * */ // 创建解析器工厂 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); // 根据解析器工厂创建解析器 DocumentBuilder builder = builderFactory.newDocumentBuilder(); // 解析xml,返回document Document document = builder.parse("src/person.xml"); // 得到所有 p1 NodeList p1_List = document.getElementsByTagName("p1"); // 得到第一个 p1 Node p1 = p1_List.item(0); // 创建sex标签,使用createElement方法 Element sex1 = document.createElement("sex"); // 创建文本,使用createTextNode方法 Text text1 = document.createTextNode("女"); // 把文本添加到sex下面,使用appendchild方法 sex1.appendChild(text1); // 把sex添加到第一个p1下面,使用appendchild方法 p1.appendChild(sex1); // 回写xml,需要使用stream流回写 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document),new StreamResult("src/person.xml")); }
6、使用jaxp修改节点内容
-
修改第一个p1下面的
内容为男 -
步骤
- 1、创建解析器工厂
- 2、根据解析器工厂创建解析器
- 3、解析xml,返回document
- 4、得到sex
- item方法
- 5、修改sex里面的值
- setTextContent方法
- 6、回写xml
-
主程序代码
public static void modifySex() throws Exception{ /** * - 1、创建解析器工厂 * - 2、根据解析器工厂创建解析器 * - 3、解析xml,返回document * - 4、得到sex - item方法 * - 5、修改sex里面的值 - setTextContent方法 * - 6、回写xml */ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.parse("src/person.xml"); // 得到sex找到第一个的sex - item方法 Node sex1 = document.getElementsByTagName("sex").item(0); // 修改sex里面的值 - setTextContent方法 sex1.setTextContent("男"); // 回写xml TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult("src/person.xml")); }
7、使用jaxp删除节点
-
删除p1节点下的
男 节点 -
步骤
- 1、创建解析器工厂
- 2、根据解析器工厂创建解析器
- 3、解析xml,返回document
- 4、获取sex元素
- 5、获取sex的父节点,使用getParentNode方法
- 6、删除使用父节点删除,使用removeChild方法
- 7、回写xml
-
主程序代码
public static void delSex() throws Exception{ /** * - 1、创建解析器工厂 * - 2、根据解析器工厂创建解析器 * - 3、解析xml,返回document * - 4、获取sex元素 * - 5、获取sex的父节点,使用getParentNode方法 * - 6、删除使用父节点删除,使用removeChild方法 * - 7、回写xml */ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.parse("src/person.xml"); // 获取sex元素,获得第一个sex Node sex1 = document.getElementsByTagName("sex").item(0); // 获取sex的父节点,使用getParentNode方法 Node p1 = sex1.getParentNode(); // 删除使用父节点删除,使用removeChild方法 p1.removeChild(sex1); // 回写xml TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document),new StreamResult("src/person.xml")); }
8、使用jaxp遍历节点
-
把xml中的所有元素名称打印出来
-
步骤
- 1、创建解析器工厂
- 2、根据解析器工厂创建解析器
- 3、解析xml,返回document
- 使用递归实现
- 4、得到根节点
- 5、得到根节点子节点
- 6、得到根节点子节点的子节点
-
注意:这里有两个难点,一个是递归方法的实现,还有一个就是剔除xml文件内的空格符号(做一个判断即可),得到相应的节点
-
主程序代码
public static void listElement() throws Exception{ /** * - 1、创建解析器工厂 * - 2、根据解析器工厂创建解析器 * - 3、解析xml,返回document * - ==使用递归实现== * - 4、得到根节点 * - 5、得到根节点子节点 * - 6、得到根节点子节点的子节点 */ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.parse("src/person.xml"); // 编写一个递归方法 list(document); } public static void list(Node node) { // 判断是否有空格,没有空格就打印 if(node.getNodeType() == Node.ELEMENT_NODE){ System.out.println(node.getNodeName()); } // 得到一层子节点 NodeList list = node.getChildNodes(); // 遍历 list for (int i = 0; i < list.getLength(); i++) { // 得到每一个节点 Node node1 = list.item(i); // 继续得到子节点 list(node1); } }
七、xml约束之一Schema
1、Schema简介
- XML Schema也是一种用于定义和描述XML文档结构与内容的模式语言,其出现是为了克服DTD的局限性
- XML Schema vS DTD:
- XML Schema符合XML语法结构。
- DOM、SAX等XML API很容易解析出XML Schema文档中的内容。
- XML Schema对名称空间支持得非常好。
- XML SchemakXML DTD支持更多的数据类型,并支持用户自定义新的数据类型。
- XML Schema定义约束的能力非常强大,可以对XML实例文档作出细致的语义限制。
- XML Schema不能像DTD样定义实体,比DTD更复杂,但XML Schema现在已是w3c组织的标准,它正逐步取代DTD。
- 总结:
- dtd语法:<!ELEMENT元素名称约束>
- schema符合xml的语法,xml语句
- 一个xml中可以有多个schema,多个schema使用名称空间区分(类似于java包名)
- dtd里面有PCDATA类型,但是在schema里面可以支持更多的数据类型
- 比如年龄只能是整数,在schema可以直接定义一个整数类型
- schema语法更加复杂,schema目前不能替代dtd
2、Schema的开发过程
(1)Schema的一些概念
-
XML Schema文件自身就是一个XML文件,但它的扩展名通常为.xsd
-
和XML文件一样,一个XML Schema文档也必须有一个根结点,但这个根结点的名称为Schema
-
应用schema约束开发xml过程

-
编写了一个XML Schema约束文档后,通常需要把这个文件中声明的元素绑定到一个URI地址上,这个URI地址叫
namespace名称空间,以后XML文件就可以通过这个URI(即名称空间)引用绑定指定名称空间的元素。
(2)Schema的文档基本结构
-
在W3C XML schema规范中规定:所有的Schema文档都使用
作为其根元素 <?xml version="1.0"?> <schema> ... </schema> -
元素可以包含一些属性。一个XML schema声明看起来经常以如下的形式出现 <schema xmlns="htp://www.w3.org/2001/XMl Schema targetNamespace="htip://www.itcast.cn/20140213" elementFormDefault="qualified"> -
Schema开发过程流程图

-
创建Schmea步骤
-
创建一个schema文件后缀名是.xsd
- 根节点
- 根节点
-
在schema文件里面下的根节点
写入如下属性 -
属性
-
xmlns="http://www.w3.org/2001/XMLSchema"--表示当前xml文件是一个约束文件
-
targetNamespace="http://www.itcast.cn/20240402"--使用schema约束文件,直接通过这个地址引入约束文件
-
elementFormDefault="qualified"
<?xml version="1.0" encoding="utf-8" ?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.itcast.cn/20240402" elementFormDefault="qualified"> </schema>
-
-
步骤
(1)看xml文件中有多少个元素,就创建多少个。 -
例如,person.xml文件里有三个标签person,name,age。那么在schema文件里
根下添加
3个<schema> <element name=""></element> <element name=""></element> <element name=""></element> </schema>
(2)看简单元素和复杂元素
-
复杂元素,需要在
标签下添加 和 标签, :表示复杂类型 :表示有顺序 - 格式如下:
<element name=""> <complexType> <sequence> 子元素 </sequence> </complexType> </element> -
简单元素,需写在复杂元素里,例如person.xml文件里有三个标签person,name,age。name和age都是person的子元素,也是简单元素,相应的也可以规范其类型name为string类型,age为整型。写入schema文件格式如下:
<element name="person"> <complexType> <sequence> <element name="name" type="string"></element> <element name="age" type="int"></element> </sequence> </complexType> </element>
(3)在被约束文件(xml文件)里面引入约束文件(Schema文件)
<?xml version="1.0" encoding="UTF-8"?> <person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.itcast.cn/20240402" xsi:schemaLocation="http://www.itcast.cn/20240402 textSchema.xsd"> <name>张三</name> <age>20</age> </person>- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"--表示xml是一个被约束文件,其中使用“ :”给xmlns起别名为xsi。
- xmlns="http://www.itcast.cn/20240402"--是约束文件里的targetNamespace
- xsi:schemaLocation="http://www.itcast.cn/20240402 textSchema.xsd"
- http://www.itcast.cn/20240402为targetNamespace
- textSchema.xsd为约束文档的地址路径
- xsi:schemaLocation格式为:targetNamespace地址 空格 约束文档的地址路径
-
-
3、XSD指示器
通过指示器,我们可以控制在文档中使用元素的方式。
有七种指示器:
Order 指示器:用于定义元素的顺序
-
All指示器
-
-- 规定子元素可以按照任意顺序出现,且每个子元素必须只出现一次 <element name="person"> <complexType> <all> <element name="child_name" type="string"/> <all> <complexType> <element>
-
-
Choice 指示器
-
-- 只能出现子元素内的其中一个 <element name="person"> <complexType> <choice> <element name="child_name" type="string"/> <element name="mother_name" type="string"/> <choice> <complexType> <element>
-
-
Sequence
-
-- 规定子元素必须按照特定的顺序出现 <element name="person"> <complexType> <sequence> <element name="child_name" type="string"/> <element name="mother_name" type="string"/> <sequence> <complexType> <element>
-
Occurrence 指示器:用于定义某个元素出现的频率
-
maxOccurs:规定某个元素可出现的最大次数
<element name="person"> <complexType> <sequence> <element name="child_name" type="xs:string" maxOccurs="10"/> <sequence> <complexType> <element> -
minOccurs:可规定某个元素能够出现的最小次数
<element name="person"> <complexType> <sequence> <element name="child_name" type="xs:string" maxOccurs="10" minOccurs="0"/> <sequence> <complexType> <element>
Group 指示器:用于定义相关的数批元素
-
Group name:元素组
-
元素组通过 group 声明进行定义:
<group name="组名称"> ... <group> -
必须在 group 声明内部定义一个 all、choice 或者 sequence 元素
<group name="persongroup"> <sequence> <element name="firstname" type="string"/> <element name="lastname" type="string"/> </sequence> </group> -
group 定义完毕以后,就可以在另一个定义中引用它
<group name="persongroup"> <sequence> <element name="firstname" type="string"/> <element name="lastname" type="string"/> <element name="birthday" type="date"/> </sequence> </group> <element name="person" type="personinfo"/> <complexType name="personinfo"> <sequence> <group ref="persongroup"/> <element name="country" type="string"/> </sequence> </complexType>
-
-
attributeGroup name:属性组
-
属性组通过 attributeGroup 声明来进行定义:
<xs:attributeGroup name="组名称"> ... </xs:attributeGroup> -
定义了名为 "personattrgroup" 的一个属性组:
<xs:attributeGroup name="personattrgroup"> <xs:attribute name="firstname" type="xs:string"/> <xs:attribute name="birthday" type="xs:date"/> </xs:attributeGroup> -
定义完毕属性组之后,就可以在另一个定义中引用它:
<xs:attributeGroup name="personattrgroup"> <xs:attribute name="firstname" type="xs:string"/> <xs:attribute name="birthday" type="xs:date"/> </xs:attributeGroup> <xs:element name="person"> <xs:complexType> <xs:attributeGroup ref="personattrgroup"/> </xs:complexType> </xs:element>
-
4、XSD定义属性(attribute)
简易元素无法拥有属性。假如某个元素拥有属性,它就会被当作某种复合类型。但是属性本身总是作为简易类型被声明的。
写在复杂元素里面
写在之前
声明属性的语法
<attribute name="id1" type="int" use="required"></attribute>
- name:属性名称
- type:属性类型int stirng
- use:属性是否必须出现required
5、复杂的schema约束案例
两个约束文件名为company.xsd和department.xsd,一个被约束文件名为company.xml
-
company.xsd文件代码
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/company" elementFormDefault="qualified"> <element name="company"> <complexType> <sequence> <element name="employee"> <complexType> <sequence> <!-- 引用任何一个元素 --> <any></any> <!-- 员工名称 --> <element name="name"></element> </sequence> <!-- 为employee元素添加属性 --> <attribute name="age" type="int"></attribute> </complexType> </element> </sequence> </complexType> </element> </schema> -
department.xsd文件代码
<?xml version="1.0" encoding="UTF-8" ?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/department" elementFormDefault="qualified"> <!-- 部门名称 --> <element name="deptname" type="string"></element> </schema> -
company.xml文件代码
<?xml version="1.0" encoding="utf-8" ?> <!-- 数据文件 引用多个Schema--> <company xmlns="http://www.example.org/company" xmlns:dept="http://www.example.org/department" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/company company.xsd http://www.example.org/department department.xsd" > <employee age="30"> <!-- 部门名称 --> <dept:deptname>人力资源部</dept:deptname> <!-- 员工名称 --> <name>张三</name> </employee> </company>
6、sax的解析过程
-
解析xml文件有两种技术:dom和sax
-
dom解析:根据xml的层级结构在内存中分配一个树形结构把xml中标签,属性,文本封装成对象
-
sax解析:事件驱动,边读边解析
-
在javax. xml.parsers包里面
-
SAXParser类
-
此类的实例可以从SAXParserFactory.newSAXParser()方法获得
-
parse (File f, DefaultHandler dh)
-
两个参数
第一个参数File f:xml的路径第二个参数DefaultHandler dh:事件处理器
-
-
-
SAXParserFactory类
- 实例 newInstance() 方法得到
-
-
-
-
sax执行过程图解
- 当解析到开始标签时候,自动执行startElement方法
- 当解析到文本时候,自动执行characters方法
- 当解析到结束标签时候,自动执行endElement方法
-

7、使用sax方法查询xml(只能查询)
sax方式不能实现增删改操作,只能做查询操作打印出整个文档
-
执行SAXParser类中public void parse(File f, DefaultHandler dh)方法;
- 第一个参数xml路径
- 第二个参数是事件处理器
-
创建一个类,继承事件处理器的类,重写里面的三个方法
- startElement(String uri, String localName, String qName, Attributes attributes)
- characters(char[] ch, int start, int length)`
- endElement(String uri, String localName, String qName)`
-
获取到所有的name元素的值
- 定义一个标志变量 flag= false
- 判断开始方法是否是name元素,如果是name元素,把flag值设置成true
- 如果flag值是true,在characters方法里面打印内容
- 当执行到结束方法时候,把flag值设置成false
-
获取第一个name元素的值
-
定义一个成员变量idx=1
-
在结束方法时候,idx+1 idx++
-
想要打印出第一个name元素的值,
-
在characters方法里面判断,
-
判断flag=true并且idx==1,在打印内容
-
-
-
主程序代码
public class TextSax { public static void main(String[] args) throws Exception { /** * 1.创建解析器工厂 * 2.创建解析器 * 3.执行parse方法 * 4.自己创建一个 MyDefault 类,继承DefaultHandler * 5.重写类里的三个方法 */ // 创建解析器工厂 SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); // 创建解析器 SAXParser saxParser = saxParserFactory.newSAXParser(); // 执行parse方法 //saxParser.parse("src/person.xml",new MyDefault()); saxParser.parse("src/person.xml",new MyDefault1()); } }-
获取peroson.xml文件的所有内容
// 获取peroson.xml文件的所有内容 class MyDefault extends DefaultHandler{ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.print("<" + qName + ">"); } @Override public void characters(char[] ch, int start, int length) throws SAXException { System.out.print(new String(ch,start,length)); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { System.out.print("</" + qName + ">"); } } -
获取person.xml文件name元素内的值
// 获取person.xml文件name元素内的值 class MyDefault1 extends DefaultHandler{ boolean flag = false; int ids = 1; @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // 判断 qName是否为 name 元素, if ("name".equals(qName)){ flag = true; } } @Override public void characters(char[] ch, int start, int length) throws SAXException { // 当 flag值是true,表示解析到name元素 if (flag == true && ids == 1){ System.out.println(new String(ch,start,length)); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { // 把 flag设置成 false,表示name 元素结束 if ("name".equals(qName)){ flag = false; ids++; } } }
-
八、dom4j 解析 xml
1、dom4j简介
-
dom4j 是一个组织,针对xml解析,提供解析器dom4j。而dom4j不是javase的一部分,想要使用需要怎么做?
- 导入dom4j提供jar包
- 创建一个文件夹lib--复制dom4j的jar包到lib文件下,
- 若是IDEA环境下,右键点击jar包,Add as Library 即可;若是Eclipse环境下,右键点击jar包,build path -- add to buildpath--看到jar包,变成奶瓶样子,表示导入成功
-
得到document
SAXReader reader = new SAXReader(); Document document = reader.read(url); -
document的父接口是Node
- 如果在document里面找不到想要的方法,到Node接口里面去找
-
document里面的方法:getRootElement():获取根节点返回的是Element
-
Element也是一个接口,父接口也是Node
- Element和Node里面方法
- getParent():获取父节点
- addElement():添加标签
- element (qname):表示获取标签下面的第一个子标签
- qname:标签的名称
- elements (qname):获取标签下面是这个名称的所有子标签(一层)
- qname:标签名称
- elements():获取标签下面的所有一层子标签
2、使用dom4j查询xml
-
查询person.xml文件内所有name元素里面的值
-
1、创建解析器
-
2、得到document
-
3、得到根节点getRootElement()返回Element
-
4、得到所有的p1标签
- elements ( "p1")返回list集合
- 遍历list得到每一个p1
-
5、得到name
- 在p1下面执行element ( "name")方法返回Element
-
6、得到name里面的值
- getText方法得到值
-
方法代码
public static void selectName() throws Exception { /** * - 1、创建解析器 * - 2、得到document * - 3、得到根节点getRootElement()返回Element * - 4、得到所有的p1标签-elements ( "p1")返回list集合-遍历list得到每一个p1 * - 5、得到name - 在p1下面执行element ( "name")方法返回Element * - 6、得到name里面的值 - getText方法得到值 */ // 创建解析器 SAXReader saxReader = new SAXReader(); // 得到document Document document = saxReader.read("src/person.xml"); // 得到根节点 Element root = document.getRootElement(); // 得到所有的p1标签 List<Element> p1_list = root.elements("p1"); // 遍历 p1_list 列表 for (Element element : p1_list) { // element是每一个p1元素 // 获取 p1 标签下的 name 元素 Element name1 = element.element("name"); // 获取 name1 元素内的值 String s = name1.getText(); System.out.println(s); } }
-
-
查询第一个name元素的值
-
1、创建解析器
-
2、得到document
-
3、得到根节点
-
4、得到第一个p1元素
- element ( "p1")方法返回Element
-
5、得到p1下面的name元素
- element( "name")方法返回Element
-
6、得到name元素里面的值
- getText方法
-
方法代码
// 获取第一个name元素内的值 public static void selectSin() throws Exception{ SAXReader saxReader = new SAXReader(); Document document = saxReader.read("src/person.xml"); Element root = document.getRootElement(); // 得到第一个p1元素 Element p1 = root.element("p1"); // 得到p1下面的name元素 Element name1 = p1.element("name"); // 得到name元素里面的值 String s1 = name1.getText(); System.out.println(s1); }
-
-
获取第二个name元素的值
-
1、创建解析器
-
2、得到document
-
3、得到根节点
-
4、得到所有的p1
- 回list集合
-
5、遍历得到第二个p1
- 使用list下标得到aet方法,集合的下标从0开始,想要得到第二个值,下标写1
-
6、得到第二个p1下面的name
- element ( "name")方法返回Element
-
7、得到name的值
-
方法代码
// 获取第二个name元素内的值 public static void selectSecond() throws Exception{ SAXReader saxReader = new SAXReader(); Document document = saxReader.read("src/person.xml"); Element root = document.getRootElement(); // 得到所有的p1 List<Element> p1_list = root.elements("p1"); // 遍历得到第二个p1 Element p2 = p1_list.get(1); // 得到第二个p1下面的name Element name1 = p2.element("name"); // 得到name的值 String s1 = name1.getText(); System.out.println(s1); }
-
3、使用dom4j实现添加操作
-
在第一个p1标签末尾添加一个元素
女 -
步骤
-
1、创建解析器源
-
2、得到document
-
3、得到根节点
-
4、获取到第一个p1
- 使用element方法
-
5、在p1下面添加元素
- 在p1上面直接使用addElement("标签名称")方法返回一个Element
-
6、在添加完成之后的元素下面添加文本
- 在sex上直接使用setText("文本内容")方法
-
7、回写xml
-
使用OutputFormat格式化 一个值,然后将这个值传给new XMLWriter()方法。使用createPrettyPrint方法,表示一个漂亮的格式
OutputFormat outputFormat = OutputFormat.createPrettyPrint(); -
使用类XMLWriter类进行回写,需要new这个类,传递两个参数
-
第一个参数是xml文件路径new Fileoutputstream("路径")
-
第二个参数是格式化类的值
-
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/person.xml"),outputFormat);
-
-
使用write()方法写入document;
-
再关闭流。
-
-
方法代码
public static void addSex() throws Exception{ SAXReader saxReader = new SAXReader(); Document document = saxReader.read("src/person.xml"); Element root = document.getRootElement(); // 获取到第一个p1 Element p1 = root.element("p1"); // 在p1下面添加元素 Element sex = p1.addElement("sex"); // 在sex元素下面添加文本 sex.setText("女"); // 回写xml OutputFormat outputFormat = OutputFormat.createPrettyPrint(); XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/person.xml"),outputFormat); xmlWriter.write(document); xmlWriter.close(); }
-
4、使用dom4j实现特定位置添加元素
-
在第一个p1下面的age标签之前添加
野鸡大学 -
步骤
- 1、创建解析器
- 2、得到document
- 3、得到根节点
- 4、获取到第一个p1
- 5、获取p1下面的所有的元素
- elements ()方法返回list集合
- 使用list里面的方法,在特定位置添加元素
- 首先创建元素,在元素下面创建文本
- 使用DocumentHelper类方法createElement创建标签
- 把文本添加到标签下面使用setText("文本内容")方法
- list集合里面的add(int index, Eelement)
- 第一个参数是位置下标,从0开始
- 第二个参数是要添加的元素
-
6、回写xml
-
方法代码
// 在第一个p1下面的age标签之前添加<school>野鸡大学</schlool> public static void addAgeBefore() throws Exception{ SAXReader saxReader = new SAXReader(); Document document = saxReader.read("src/person.xml"); Element root = document.getRootElement(); // 获取到第一个p1 Element p1 = root.element("p1"); // 获取p1下面的所有的元素 List<Element> p1_list = p1.elements(); // 创建school元素 Element school = DocumentHelper.createElement("school"); // 在school元素下,创建文本 school.setText("野鸡大学"); // 在p1_list集合里面的add(int index, Eelement)添加school元素 p1_list.add(1,school); // 回写xml OutputFormat format = OutputFormat.createPrettyPrint(); XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/person.xml"), format); xmlWriter.write(document); xmlWriter.close(); }
5、dom4j里得封装方法
-
可以将对得到document的操作和回写xml的操作,封装成方法也可以把传递的文件路径,封装成一个常量
-
好处:可以提高开发速度,可以提交代码可维护性
-比如想要修改文件路径(名称),这个时候只需要修改常量的值就可以了,其他代码不需要做任何改变。
-
-
创建一个名为Utils包,再创建名为Dom4jUtils类进行封装操作
-
将传递的文件路径封装成一个常量
public static final String PATH = "src/person.xml"; -
对得到document的操作封装为Document getDocument(String path)方法
public static Document getDocument(String path) { try { // 创建解析器 SAXReader saxReader = new SAXReader(); // 得到document Document document = saxReader.read(path); return document; } catch (Exception e) { e.printStackTrace(); } return null; } } -
回写xml的操作封装为xmlWriters(String path, Document document)方法
public static void xmlWriters(String path,Document document){ try { OutputFormat format = OutputFormat.createPrettyPrint(); XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(path), format); xmlWriter.write(document); xmlWriter.close(); } catch (Exception e) { e.printStackTrace(); } }
-
-
总程序代码
import org.dom4j.Document; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; public class Dom4jUtils { // 将传递的文件路径封装成常量 public static final String PATH = "src/person.xml"; // 返回都doucment public static Document getDocument(String path) { try { // 创建解析器 SAXReader saxReader = new SAXReader(); // 得到document Document document = saxReader.read(path); return document; } catch (Exception e) { e.printStackTrace(); } return null; } // 回写xml的方法 public static void xmlWriters(String path,Document document){ try { OutputFormat format = OutputFormat.createPrettyPrint(); XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(path), format); xmlWriter.write(document); xmlWriter.close(); } catch (Exception e) { e.printStackTrace(); } } } -
如何使用封装方法?
-
因为都是static方法,直接 类名.方法名() 即可
// 返回的document Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH); // 回写xml Dom4jUtils.xmlWriters(Dom4jUtils.PATH,document);
-
6、使用dom4j实现修改节点操作
-
修改第一个p1下面的age元素的值为
30 -
步骤
- 1、得到document
- 2、得到根节点,然后再得到第一个p1元素
- 3、得到第一个p1下面的age
- element ("")方法
- 4、修改值是30
- 使用setText ( "文本内容")方法
- 5、回写xml
-
方法代码
// 修改第一个p1下面的age元素的值为<age>30</age> public static void modifyAge() throws Exception{ // 得到document Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH); // 得到根节点 Element root = document.getRootElement(); // 得到第一个p1元素 Element p1 = root.element("p1"); // 得到第一个p1元素下的age Element age = p1.element("age"); // 修改值age为30,使用setText()方法 age.setText("30"); // 回写xml Dom4jUtils.xmlWriters(Dom4jUtils.PATH, document); }
7、使用dom4j实现删除节点操作
-
删除第一个p1下面的
野鸡大学 元素 -
步骤
- 1、得到document
- 2、得到根节点
- 3、得到第一个业标签
- 4、得到第一个p1下面的school元素
- 5、删除(使用p1删除school)
- 得到school的父节点
- 第一种直接使用getRootElement()得到p1
- 第二种使用方法getParent()方法得到
- 删除操作
- 在p1上面执行remove方法删除节点
- 得到school的父节点
- 6、回写xml
-
方法代码
// 删除第一个p1下面的<school>野鸡大学</school>元素 public static void delSch() { Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH); Element root = document.getRootElement(); // 得到第一个p1标签 Element p1 = root.element("p1"); // 得到第一个p1元素下的school元素 Element school = p1.element("school"); // 删除操作 p1.remove(school); // 回写xml Dom4jUtils.xmlWriters(Dom4jUtils.PATH, document); }
8、使用dom4j获取属性操作
-
获取第一个p1里面的属性id1的值
-
步骤
- 1、得到document
- 2、得到根节点
- 3、得到第一个p1元素
- 4、得到p1里面的属性值
- p1.attributevalue ( "id1");
- 在p1上面执行这个方法,里面的参数是属性名称
-
程序代码
// 获取第一个p1里面的属性id1的值 public static void getValues() throws Exception{ Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH); Element root = document.getRootElement(); // 得到第一个p1元素 Element p1 = root.element("p1"); // 得到p1里面的属性值 String id1 = p1.attributeValue("id1"); System.out.println(id1); }
九、XPath
1、XPath简介
XPath 是一门在 XML 文档中查找信息的语言。XPath 用于在 XML 文档中通过元素和属性进行导航。
一、什么是 XPath?
- XPath 使用路径表达式在 XML 文档中进行导航
- XPath 包含一个标准函数库
- XPath 是 XSLT 中的主要元素
- XPath 是一个 W3C 标准
二、XPath 路径表达式
XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。
三、XPath 标准函数
XPath 含有超过 100 个内建的函数。这些函数用于字符串值、数值、日期和时间比较、节点和 QName 处理、序列处理、逻辑值等等。
2、XPath语法
XPath 使用路径表达式来选取 XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。
以下面的xml文件为例
<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title lang="eng">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>
1.选取节点
-
XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。
-
最有用的路径表达式:
表达式 描述 nodename 选取此节点的所有子节点。 / 从根节点选取。 // 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 . 选取当前节点。 .. 选取当前节点的父节点。 @ 选取属性。 -
示例
列出了一些路径表达式以及表达式的结果:
路径表达式 结果 bookstore 选取 bookstore 元素的所有子节点。 /bookstore 选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! bookstore/book 选取属于 bookstore 的子元素的所有 book 元素。 //book 选取所有 book 子元素,而不管它们在文档中的位置。 bookstore//book 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。 //@lang 选取名为 lang 的所有属性。
2.谓语(Predicates)
谓语用来查找某个特定的节点或者包含某个指定的值的节点。
谓语被嵌在方括号中。
-
示例
路径表达式 结果 /bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素。 /bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素。 /bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素。 /bookstore/book[position()❤️] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 //title[@lang] 选取所有拥有名为 lang 的属性的 title 元素。 //title[@lang='eng'] 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。 /bookstore/book[price>35.00] 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 /bookstore/book[price>35.00]/title 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。
4.通配符
XPath 通配符可用来选取未知的 XML 元素。
| 通配符 | 描述 |
|---|---|
| * | 匹配任何元素节点。 |
| @* | 匹配任何属性节点。 |
| node() | 匹配任何类型的节点。 |
-
示例
路径表达式 结果 /bookstore/* 选取 bookstore 元素的所有子元素。 //* 选取文档中的所有元素。 //title[@*] 选取所有带有属性的 title 元素。
5.选取若干路径
通过在路径表达式中使用 “|” 运算符,您可以选取若干个路径。
-
示例
路径表达式 结果 //book/title | //book/price 选取 book 元素的所有 title 和 price 元素。 //title | //price 选取文档中的所有 title 和 price 元素。 /bookstore/book/title | //price 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。
3、使用dom4j支持xpath具体操作
- 默认的情况下, dom4j不支持xpath
- 如果想要在dom4j里面是有xpath
- 第一步需要,引入支持xpath的jar包,使用jaxen-1.1-beta-6.jar
- 需要把jar包导入到项目中
- 在dom4j里面提供了两个方法,用来支持xpath
- selectNodes("xpath表达式") -- 获取多个节点
- selectsingleNode ( "xpath表达式") -- 获取一个节点
1.使用xpath实现:查询xml中所有name元素的值
-
所有name元素的xpath表示://name
-
使用selectNodes ( "//name");
-
步骤
- 1、得到document
- 2、直接使用selectNodes (" //name")方法得到所有的name元素
-
方法代码
// 查询xml中所有name元素的值 public static void xpath_SelectName() throws Exception{ // 得到document Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH); // 直接使用selectNodes (" //name")方法得到所有的name元素 List<Node> nameList = document.selectNodes("//name"); // 遍历 nameList列表,获取每一个name元素内的值 for (Node node:nameList) { // node是每一个name元素 // 得到name元素里面的值 String s = node.getText(); System.out.println(s); } }
2.使用xpath查询xml中第一个p1下的name元素内的值
-
XPath查询第一个p1下name元素内的值的语法:
-
//p1[@id1='AAAA']/name
-
-
在java中类使用到
selectSingleNode ( "//p1[@id1='AAAA']/name") -
步骤和代码
-
1、得到document
-
2、直接使用selectSingleNode方法实现
- xpath : //p1[@id1= 'AAAA' ] /name
-
得到document
-
Document document = Dom4jutils.getDocument (Dom4jutils.PATH);
-
-
直接使用selectSingleNode方法,获得name元素
-
Node name1 = document.selectSingleNode("//p1[@id1='AAAA' ]/name");
-
-
得到name元素里面的值
-
string s1 = name1.getText(); system.out.println(s1);
-
-
-
方法代码
// 查询xml中第一个p1下的name元素内的值 public static void xpath_SelectFirstName() throws Exception{ * - 1、得到document * - 2、直接使用selectsingleNode方法实现 * - xpath : //p1[@id1= 'AAAA' ]/name * - 直接使用selectsingleNode方法,获得name元素 */ // 得到document Document document = Dom4jUtils.getDocument(Dom4jUtils.PATH); // 直接使用selectsingleNode方法实现 Node name = document.selectSingleNode("//p1[@id1= 'AAAA' ]/name"); // 得到name元素里的值 String s = name.getText(); System.out.println(s); }

浙公网安备 33010602011771号