简单xml的使用以及xml的解析dom4j和jaxp

2023-11-14

1 xml的简介  w3c组织发布

extensible markup Language :可扩展标记型语言 也是使用标签操作

可扩展:html里面的标签是固定,每个标签都有特定的含义

xml标签可以自己定义,可以写中文的标签

用途:显示数据(不是主要功能) ,主要为了存储数据

两个版本:1.0 1.1 使用的都是1.0版本(1.1不能向下兼容)

2 xml的应用

不同系统之间传输数据

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

经常用在文件配置

比如现在连接数据库,肯定得知道数据库的用户名和密码,数据名称

如果修改数据库的信息,不需要修改源代码,只要修改配置文件就可以

3 xml的语法

1 xml的文档声明    后缀名为.xml  如果写xml,第一步必须要有一个文档声明(写了文档声明之后,表示写xml文件的内容)

<?xml version="1.0" encoding="gbk"?>

文档声明必须写在第一行第一列

属性:version :xml的版本     encoding:xml编码  gbk  utf-8  iso8859-1(不包含中文)

standalone : 是否依赖其他文件存在

    xml问题的解决:保存时候的编码和设置打开时的编码一致,不会出现乱码

2 定义元素(标签)

3 定义属性

4 特殊字符

5 CDATE区

6 PI指令

7 注释

5 xml元素的定义

标签定义  例:<person></person> 标签有开始必须要有结束

标签没有内容,可以在标签内结束:<aa/>

标签可以嵌套,但必须合理嵌套

一个xml中只能有一个根标签,其他标签都是这个标签下面的标签

注意:在xml中把空格和换行都当成内容来解析

<aa>AAAAA</aa>

<aa>

AAAA

</aa>

以上两端代码含义不一样

xml中标签的名称规则

1 xml区分大小写

<P><p> 这两个标签是不一样的

2 xml的标签不能以数字和下划线开头

3 xml的标签不能以xml ,XML.Xml等开头 <Xmla><Xmlb><xmlc> :这些都是不正确的

4 xml的标签不能包含空格或冒号  <a b><b:c>:这些是不正确的

6 xml中属性的定义

<person id1="aaa">  </person>

属性定义的要求

1 一个标签可以有多个属性

2 属性名称不能相同

3 属性名称和属性值之间使用= 属性值使用引号包起来(可以使用单双引号)

4 xml属性名称规范与元素规范是一致的

7 xml中的注释

写法<!--  -->

注意:注释不能有嵌套

8 xml中的特殊字符

如果想要在xml中显示 a<b 不能正常显示,因为把<当做标签

需要转义:&: &amp;     <:  &lt;    > : &gt;    " : &quot;    ' : &apos;    (后面需要;号)

9 CDATA区

可以解决多个字符都需要转义的操作 

把这些内容放到CDATA区里面,不需要转义

写法<![CDATA[ 内容 ]]>

例<![CDATA[ <b>if(a<b && b<c && d>f) {}</b> ]]>

把特殊字符,当做文本内容,而不是标签

10 PI指令(处理指令)

可以在xml中设置样式

写法:<?xm-stylesheet type="text/css" href="css的路径"?>

设置样式,只能对英文标签名称起作用,对于中文的标签名称不起作用

11 语法总结

所有xnl元素都必须有关闭标签

xml标签对大小写敏感

xml必须有正确的嵌套顺序

xml文档必须有根元素(只有一个)

xml的属性值必须加引号

特殊字符必须转义  ---CDATA

xml中的空格,回车换行在解析时会被保留

12 xml的约束

为什么需要约束?规定xml中只能出现的元素,这个时候需要约束

xml的约束的技术:dtd约束和schema约束

13 dtd的快速入门

创建一个文件 后缀名 .dtd

步骤: 1 看xml中有多少个元素,有几个元素,在dtd文件中写几个<!ElEMENT>

      2 判断元素是简单元素还是复杂元素

复杂元素:有子元素的元素 <!ELEMENT 元素名称  (子元素)>

简单元素: 没有子元素  <!ELEMENT 元素名称 (#PCDATA)>

3 需要在xml文件中引入dtd文件

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

打开xml文件使用浏览器打开的,浏览器只负责校验xml的语法,不负责校验约束

如果想要校验xml的约束,需要使用工具(myeclipse工具)

14 dtd的三种引入方式

1 引入外部的dtd文件

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

2 使用内部的dtd文件

<!DOCTYPE 根元素名称[

<!ELEMENT person (name,age)>

<!ELEMENT name (#PCDATA)>

<!ELEMENT age (#PCDATA)>

]>

3 使用外部的dtd文件(网络上传的dtd文件)

<!DOCTYPE 根元素 PUBLIC “DTD名称” “DTD文档的URL”> (框架structs2 使用的方式)

15 使用dtd定义元素

语法:<!ELEMENT 元素名 约束>

简单元素:<!ELEMENT name (#PCDATA)>  (#PCDATA):约束name是字符串类型

EMPTY: 元素为空 (没有内容)(不用加括号)

ANYY:  任意元素

复杂元素:<!ELEMENT person (name,age,sex)> 各元素只能出现一次

     表示子元素出现的次数

+:表示一次或者多次

?;表示零次或者一次

*:表示零次或者多次

子元素直接使用逗号进行隔开:表示元素出现的顺序

子元素直接使用|隔开:表示元素只能出现其中的任意一个

16 使用dtd定义属性

语法:<!ATTLIST 元素名称

 属性名称 属性类型 属性约束

      >

属性类型:CDATA::字符串    枚举:(aa|bb|cc) 表示只能在一定范围内出现值,但是只能每次出现其中一个

ID :值只能是字母或者下划线卡头

属性的约束:#REQUIRED :表示该属性必须出现

#IMPLIED:属性可有可无

#FIXED:表示一个固定的一个值 例:#FIXED "AAA"  属性的值必须是设定的这个值

直接值: 例:"WWW" 不写属性,使用直接值,写了属性,使用设置的值

17 实体的定义

语法<!ELEMENT 实体名称 “实体的值”>   引用实体 &实体名称

定义实体需要写在内部dtd里面,如果写在外部的dtd里面,在某些浏览器下,内容得不到

18 xml的解析的简介

xml的解析方式:dom 和 sax

dom:根据xml的层级结构在内存中分配一个树形结构,把xml的标签,属性和文本都封装成对象

缺点:如果文件过大,造成内存溢出

优点:很方便实现增删改操作

sax方式解析

采用事件驱动,边读边解析,从上到下,一行一行的解析,解析到某一个对象,返回对象名称

缺点:不能实现增删改操作

优点:如果文件过大,不会造成内存溢出,方便实现查询操作

想要解析xml,首先需要解析器

不同的公司和组织提供了针对dom和sax方式的解析器,通过api方式提供

sun公司提供了针对dom和sax解析器 jaxp

dom4j组织:dom4j             jdom组织:jdom

19 jaxp的api查看

jaxp是javase的一部分

jaxp解析器在jdk的javax.xml.parseers包里面

四个类:分贝针对dom和sax解析使用的类

dom:   DocumentBuilder :解析器类 这个类是一个抽象类 不能new 此类的实例

DocmentBuilderFactory.newDocumentBuilder()方法获取 DocmentBuilderFactory :也是一个抽象类  通过newInstance() 获取DocumentBuilderFactory获取实例

parse(”xml路径“) 返回的是Document整个文档 返回的docunment是一个接口,父节点是Node,如果在docunment找不到方法,可以到Node去找

 在document里面的方法

getElementsByTagName(String tagname)  这个方法可以得到标签 返回集合NodeList

createElement(String tagname)  创建标签

createTextNode(String data) 创建文本 

appendChild(Node newChild) 把文本添加到标签下面

removeChild(Node oldChild) 删除节点

getParentNode() 获取父节点

NodeList    方法: getLength() 可以得到集合的长度 item(int index) 下标取到具体的值

sax:   SAXParser:解析器类  SAXParseFactory:解析器工厂

20 使用jaxp实现查询操作

查询xml中所有的name元素的值

 * 1 创建解析器工厂 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
* 2 根据解析器工厂创建解析器 DocumentBuilder builder = builderFactory.newDocumentBuilder();
* 3 解析xml返回document Document document = builder.parse("src/1.xml");
* 4 得到所有的name元素
         

21 使用jaxp添加节点

在第一个标签下面添加一个节点

步骤:

*1 创建解析器工厂 2 根据解析器工厂创建解析器 3 解析xml返回document 
* 4 得到第一个标签 使用item方法
* 5 创建sex标签createElement
* 6 创建文本createTextNode
* 7 把文本添加到sex下面appChild
* 8 把sex添加到第一标签下面
* 9 回写xml

回写代码:TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult("src/1.xml"));


22 使用jaxp修改节点

修改标签下面的内容

修改方法 setTextContent方法

23 使用jaxp删除节点

得到父节点,之后进行删除操作 removeChild()

24 使用jaxp遍历节点

把xml所有元素的名称都打印出来

递归实现:

private static void List1(Node node) {
//判断是元素类型时候打印
if(node.getNodeType() == Node.ELEMENT_NODE){
System.out.println(node.getNodeName());
}
//得到一层字节点
NodeList list = node.getChildNodes();
for(int i =0;i<list.getLength();i++){
//得到每一个节点
Node node1 = list.item(i);
List1(node1);
}

}

23

schema约束

schema符合xml的语法,xml语句

一个xml中可以有多个schema,多个schema使用名称区间划分(类似于java包名)

dtd里面有PCDATA类型,但是在schema里面可以支持更多的数据类型 比如 年龄 只能是整数,在schema可以直接定义一个整数类型

schema语法更加复杂,schema目前不能替代dtd

24 schema的快速入门

创建一个schema文件 后缀名是.xsd 根节点<schema>

在schema文件里面

属性: xmlns="http://www.w3.org/2001/XMLSchema" 表示当前xml文件是一个约束文件

targetnamespace="http://www.itcast.cn/20151111" 使用schema约束文件,直接通过这个地址引入约束文件

elementFormDefault="qualified"

步骤 1 看xml有多少个元素 <element>

2 看简单元素和复杂元素

如果复杂元素

<complexType>

<sequence> 子元素</sequence>

</complexType>

3 简单元素写在复杂元素里面

<element name="person">

<complexType>

<sequence>

<element name="name" type="string"></element>

<element name="age" type="int"></element>

</sequence>

</complexType>

</element>

4 引入文件

<person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  表示是一个被约束文件(由于有两个xmlns所以自己再起一个别名:xsi)
xmlns="http://www.itcast.cn/20151111" 是约束文档里面 targetNamespace
xsi:schemaLocation="http://www.itcast.cn/20151111 1.xsd"> targetNamespace 空格 约束文档的路径

25  <sequence> 表示元素出现的顺序

<ALL> 表示只能出现一次

 <choice>::表示元素只能出现其中一个

  maxOccurs="unbounded":表示元素出现的次数

  <any></any>:表示任意元素

可以约束属性

写在复杂元素里面,</complexType>之前

<attribute name="id1" type="int" use="required"></attribute>

name:属性名称   type:属性类型 int string use:属性是否必须出现 required

复杂schema 元素前加: schema别名(自己起的):

26 sax解析原理:

事件驱动:边读边解析

在javax.xml.parsers包里面

SAXParser

此类的实例可以从SAXParserFactory.newSAXParser() 方法获得

parse(File f,DefaultHandler dh) 两个参数 1 xml的路径 2 事件处理器

SAXParserFactory 实例 newInstance() 方法获得

sax执行过程:

当解析到开始标签的时候,自动执行startElement方法

当解析到文本时候,自动执行characters方法

当解析到结束标签时候,自动执行endElement方法

27 jaxp的sax方式解析xml

sax方式不能实现增删改操作,只能做查询操作

打印出整个文档

执行parse方法,第一个参数xml路径,第二个参数是事件处理器

创建一个类,继承事件处理器的类

重写里面的三个方法

获取到所有的name元素的值

定义一个成员变量,flag = false

判断开始方法是否是name元素,如果是name元素,把flag设置成true

如果为true,在characters方法里面打印内容

当执行到结束方法时,把flag设置成false

获取第一个name元素的值

定义一个成员变量 index = 1;

在结束方法时候,index++

想要打印第一个name元素的值,在characters方法里面判断 判断flag = true 并且index==1,在打印内容

28 使用dom4j解析xml

dom4j,是一个组织,针对xml解析,提供解析器dom4j

dom4j不是javase的一部分,想要使用第一步需要导入dom4j jar包

创建一个文件夹 复制jar包到lib下面  右键点击 jar包 build path---add buildpath (变为奶瓶样子说明导入成功)

得到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) 表示获取标签下面的第一个子标签  elements(qname) 获取标签下面的是这个名称的所有子标签       elements() 获取标签下面的所有一层子标签

29 使用dom4j 查询xml

解析从上到下

查询所有name元素里面的值

        1 创建解析器 2 得到document 3 得到根节点  getRootElement() 返回Element

4 得到所有的p1标签

elements("p1") 表示获取标签下面是这个名称的所有子标签(一层) 返回list集合

遍历list得到每一个p1

5得到name

在p1 下面执行element("name")方法 返回Element 

        6 得到name里面的值

getText方法得到值

查询第一个name元素的值

1 创建解析器
2 得到document
3 得到根节点
4 得到第一个p1元素
 element("p1") 返回Element
5 得到p1下面的name元素
6 得到name元素里面的值
  

获取第二个name元素的值

1 创建解析器
2 得到document
3 得到根节点
4 得到
所有的p1 返回list集合

5 遍历得到第二个p1 使用list下标得到get方法,集合的下标从0开始,想要得到第二个值,下标写1
5 得到p1下面的name元素
6 得到name元素里面的值
 

30 使用dom4j实现添加操作

在第一个p1标签

*1 创建解析器
*2 得到document
*3 得到根节点
*4 获取第一个p1
使用element方法
*5 在p1 下面添加元素
  在p1上面直接使用addElement("标签名称")方法 返回一个Element
*6 在添加完成之后的元素添加文本
在sex直接使用setText("文本内容")方法
*7 回写x
ml 

格式化:OutputFormat,使用 createPrettyPrint方法  表示一个漂亮的格式

使用类XMLWriter 直接new这个类,传递两个参数

第一个参数是xml文件路径 new FileOutputStream("路径")

第二个参数是格式化类的值

31 在特定的位置添加元素

在第一个p1下面的age标签之前添加<school> </school>

*1 创建解析器
*2 得到document
*3 得到根节点
*4 获取第一个p1
*5 获取p1下面所有元素 elements() 方法 返回list集合 使用list方法,在特定位置添加元素
*首先需要创建元素,在创建文本1  Element school=DocumentHelper.createElement("school"); 2 school.setText("ecit");
*3 list.add(1,school);
*add(int index,E element)
*6 回写xml

32 使用dom4j实现修改节点的操作

修改第一个p1下面的age元素的值

* 1 得到document
* 2 得到根节点,然后再得到第一个p1元素 element()
* 3 得到第一个p1下面的age  element()
* 4 修改值age setText("文本内容")
* 5 回下xml


33 使用dom4j 实现删除节点

*1 得到document
*2 得到根节点
*3 得到第一个p1标签
*4 得到第一个p1下面的school元素
*5 删除 remove() 首先得先得到父节点 getParent()
*6 回下xm
l

34 使用dom4j获取属性的值

获取第一个 p1的属性id1的值

*1 得到document
* 2 得到根节点
* 3 得到第一个p1 元素
* 4 得到p1里面属性的值 attributeValue("id1");
  在p1上面操作

35 使用dom4j支持xpath操作

可以直接获取到某个元素

第一种形式  /AAA/DDD/BBB:表示一层一层的,AAA下面DDD下面的BBB

第二种形式 //BBB: 表示和这个名称相同,只要名称是BBB,都得到

第三种形式 /*:所有元素

第四种形式  BBB[1]:  表示第一个BBB元素  BBB[last()] : 表示最后一个BBB元素

第五种形式 //BBB[@id] : 表示只要BBB元素上面有id属性,都得到

第六种形式 //BBB[@id='b1'] 表示元素名称是BBB,在BBB上面有id属性,并且id的属性值是b1

36 使用dom4j 支持xpath具体操作

默认情况下 ,dom4j不支持xpath

需要引入jar包:jaxen-1.1-beta-6.jar

在dom4j里面提供了两个方法,用来支持xpath

selectNodes("xpath表达式")  获取多个节点   selectSingleNode("xpath表达式") 获取一个节点

使用xpath实现:查询xml中所有name元素的值 xpath表示://name

1 得到document

2 直接使用document.selectNodes("//name") 方法得到所有的name元素 返回的是一个list集合

3 遍历list集合 之后使用 getText()方法得到值

使用xpath实现:获取第一个p1下面name的值

1 得到document

2 直接使用selectSingleNode方法实现 xpath://p1[@id1='aaa']/name 返回的是Node

37 实现简单的学生管理系统

使用xml当做数据库,存储学生信息

创建一个xml文件,写一些学生信息

1  增加操作

创建解析器

得到document

获取根节点

在根节点上面创建stu标签

在stu标签上面一次添加id name age  addElement方法添加

在id name age 上面一次添加值 setText

回写xml

2 删除操作(根据id删除)

创建解析器

得到document

获取所有的id 使用xpath //id 返回list集合

遍历list集合

判断集合里面的id和传递的id是否相同

如果相同,把id所在的stu删除

3 查询操作(根据id查询)

创建解析器

得到cocument

获取所有的id,返回的是list集合,遍历list集合

得到每一个id的节点的值

判断id的值和传递的值是否相同

如果相同,先获取到id的父亲节点stu

通过stu获取到name age 值 把这些值封装到一个对象里面 返回对象

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

简单xml的使用以及xml的解析dom4j和jaxp 的相关文章

随机推荐

  • 优化Mysql数据库的8个方法

    本文通过8个方法优化Mysql数据库 创建索引 复合索引 索引不会包含有NULL值的列 使用短索引 排序的索引问题 like语句操作 不要在列上进行运算 不使用NOT IN和 lt gt 操作 1 创建索引 对于查询占主要的应用来说 索引显
  • flyway出现org.flywaydb.core.api.FlywayException: Validate failed:问题解决办法

    在idea中找到数据库 如下图所示 双击flyway出现执行 mvn flyway migrate 历史记录 把最新执行看到执行失败的那条记录删掉 并提交 然后重新运行mvn flyway migrate 命令即可成功
  • Mybatis---配置文件元素属性详解

    Mybatis配置文件详解 Mybatis配置文件层次结构层次结构顺序不能改变否则会报错 Properties子元素 设置settings 类型别名typeAliases 系统定义别名 自定义别名 typeHandler类型处理器 系统定义
  • nginx代理yum

    适用场景 有多台服务器 但是只有1台服务器可以出公网 此时即可使用如下方式 进行yum代理 解决内网服务器不能yum的尴尬 一 首先需要把 etc yum repos d下的文件备份到bak 然后留一个CentOS Base repo 编辑
  • 农夫过河——python类穷举法实现

    一个农夫在河的西岸带了一匹狼 一只羊和一棵白菜 他需要把这三样东西用船带到河的东岸 然而 这艘船只能容下农夫本人和另外一样东西 如果农夫不在场的话 狼会吃掉羊 羊也会吃掉白菜 w 1 2 3 西岸初始状态 0代表没有 1代表白菜 2代表羊
  • 编译、安装和使用FANN库(环境部署)

    编译 安装和使用FANN库 环境部署 下载FANN的源代码 Github上面是官方的仓库 地址是libfann fann 它大概已经有两年时间是2 2 0版本 目前还看不到有什么活跃的提交 克隆主分支 git clone depth 1 h
  • 十个常见的Git面试题及详细解答

    Git是目前最流行的分布式版本控制系统之一 广泛应用于软件开发中 在Git面试中 面试官通常会提问一些与Git相关的问题 以评估候选人的版本控制技能和了解他们对Git的理解 本文将介绍十个常见的Git面试题 并提供详细的解答 帮助读者更好地
  • JVM 讲解

    目录 1 JVM 运行流程 2 JVM 基本组成 重要 2 1 堆 线程共享 2 2 Java 虚拟机栈 线程私有 2 3 本地方法栈 线程私有 2 4 程序计数器 线程私有 2 5 方法区 线程共享 3 OOM 4 JVM 垃圾回收算法
  • Airflow Trigger DAG with config

    1 rest api to trigger dag POST api experimental dags
  • 基于51单片机的霍尔自行车里程测速仪(含Keil程序和Proteus文件)

    系统概述 系统使用的模块有AT89C51单片机 LCD1602显示屏 霍尔测速模块 本设计采用51单片机为核心控制 使用LCD1602显示采集到的速度 霍尔测速模块进行测速 测速的原理是通过磁感应原理检测开关变化量 通过检测两个开关量的时间
  • 【javascript】闭包

    通过定时器从第一个元素开始往后 每隔一秒输出arr数组中的一个元素 但是运行过后 我们却会发现结果是每隔一秒输出一个 undefined 这是为什么呢 setTimeout 函数与for循环在调用时会产生两个独立执行上下文环境 当setTi
  • grep查找进程时,忽略grep进程本身

    ps ef grep 进程名 grep v grep grep v grep即去除结果中含有grep的进程 但是要注意如果你的进程名中本身含有grep也会被忽略 这时就需要更细致的规则 例如去除条件里加上一个空格 ps ef grep 进程
  • Matlab笔记

    1 创建矩阵 gt gt a 1 2 3 4 5 8 1 2 8 1 2 8可以是1起始值 公差 结束值 也可以是1 2 7 a 1 2 3 4 5 6 7 8 1 3 5 7 1 2 特殊矩阵 名称 函数 说明 单位矩阵 eye m n
  • leetcode链表刷题:删除中间节点

    题目如下所示 这道题正如评论区所言 最大的难度就是读懂题目本身 这道题的意思是 有一个链表 题目给了我这个链表上除了第一个和最后一个节点以外的一个中间节点 然后我要把这个中间节点给删掉 也就是说 我们能够进行操作的 是一个链表上的一个节点
  • leetcode 10. 正则表达式匹配

    2023 9 20 感觉是目前做过dp题里最难的一题了 本题首要的就是需要理解题意 翻了评论区我才发现之前一直理解的题意是错的 我原来理解的 匹配0次 是指 直接消失 不会影响到前面的字符 但是 和前一个字符其实是连体的 所以说 如果匹配0
  • 网络空间安全导论

    感谢戴银涛老师的指导 笔记时间有点儿久了 整理的时候一些图丢了 不过问题不大 网络空间安全导论 目录 1 信息安全概述 从网络信息系统的发展概述 从系统分析方法看信息与信息安全的关系 从信息安全技术史角度理解网络安全相关概念 网络信息系统安
  • 深入理解 TCP 协议:从原理到实战

    小册介绍 TCP 协议是我一直很想写的一个主题 因为 TCP 学起来实在是太痛苦了 刚参加工作时 TCP 协议一直是一个心头痛 知道皮毛 但是始终无法深入 在阅读了大量相关的书籍 做了很多网络编程方面的工作以后觉得掌握的过程太过曲折 这本小
  • 【前端代码实例】使用HTML5+CSS3+JavaScript制作一个响应式的后台管理系统~带侧边导航栏仪表盘功能

    bilibili在线视频演示地址 前端代码实例 使用HTML5 CSS3 JavaScript制作一个响应式的后台管理系统 带侧边导航栏仪表盘功能 效果图 简化版代码
  • C++学习(三十四)stdlib与cstdlib

    C语言中是有 include
  • 简单xml的使用以及xml的解析dom4j和jaxp

    1 xml的简介 w3c组织发布 extensible markup Language 可扩展标记型语言 也是使用标签操作 可扩展 html里面的标签是固定 每个标签都有特定的含义 xml标签可以自己定义 可以写中文的标签 用途 显示数据