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

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 值 把这些值封装到一个对象里面 返回对象

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值