小白的XML课笔记

小白学习 同时被 2 个专栏收录
1 篇文章 0 订阅
1 篇文章 0 订阅

XML学习

学习重点:DTD,XML,XML的基本语法,规范的XML格式文档,有效的XML文档(要写得出来),可以使用DTD去验证,可以使用命名空间,可以用Schema去验证,第四章里面Schema基础的东西要掌握,一二三四第六章会涉及一点,Xpath涉及一点,XXL(重点)其他就选讲

1,2,3,4,8,11,12章 6,7也会涉及一些,9,10,13不会涉及 Schema高级技术要理解

老师讲怎么复习:书上的例子全部都跑一遍,所有的习题自己思考全部都要做,类似的都要会,在XMLSpy中去理解

第一章:XML入门

1.1 了解XML

代码1-1 简单的XML文档

<?xml version="1.0" encoding="UTF-8"?>
<个人信息>
<姓名>田诗琪</姓名>
<生日>2011-04-11</生日>
<性别></性别>
<身高>83cm</身高>
</个人信息>

代码1-2 格式不良好的XML文档

<?xml version="1.0" encoding="UTF-8"?>
<个人信息>
<姓名>田诗琪
<生日>2011-04-11</生日>
<性别></性别>
<身高>83cm</身高>
</个人信息>

代码1-3 有效的XML文档

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE 个人信息[
<!ELEMENT 个人信息 (姓名,生日,性别,身高)>
<!ELEMENT 姓名 (#PCDATA)>
<!ELEMENT 生日 (#PCDATA)>
<!ELEMENT 性别 (#PCDATA)>
<!ELEMENT 身高 (#PCDATA)>


]>

<个人信息>
<姓名>田诗琪</姓名>
<生日>2011-04-11</生日>
<性别>女</性别>
<身高>83cm</身高>
</个人信息>


1.2 XML的语法基础

1.XML声明

<?xml version="1.0" encoding="UTF-8"?>

语法格式:

<?xml version="1.0|1.1" [encoding="编码方式"] [stanalone="yes|no"]?>

version:指明文档是遵循哪个版本的XML规范

encoding:默认是UTF-8,可以省略

standalone:指定该XML文档是否和一个外部文档配套使用,yes就表明当前XML文档是一个独立的文档

2.文档类型声明

<DOCTYPE china SYSTEM "mydtd.dtd">

这个使用了一个外部的DTD文件

<?xmlversion="1.0" encoding="UTF-8">
<!ELEMENT china(#PCDATA)>

也可以不引用外部DTD文件,直接在XML文档中给出了DTD

<!DOCTYPE china[
<!ELEMENT chin (#PCDATA)
]>

3.处理指令

<?xml - stylsheet type="text/css" href ="mycss.css" ?>

mycss.css中的代码:

China{
background-color:#ffffff;
color:red;
outline:#00ff00 dotted thick;
}

常见的处理指令

<?xml - stylsheet href="hello.css" type ="text/css" ?>
<?xml - stylsheet href="hello.xsl" type ="text/xsl" ?>

4.注释

(1)注释不能出现在XML声明之前

(2)注释不能出现在标记中

(3)注释可以包围和隐藏标记,但是在添加注释之后,要保证剩余的文本仍然是一个结构完整的XML文档

(4)字符串“–”不能在注释中出现

(5)在XML结尾,不允许注释以“–>”结尾

5.元素

区别:标记,元素和属性

(1)标记是<>所包含的对象

(2)元素是指由开始标记,结束标记,标记内容构成的

(3)属性是元素的附加属性

XML基本语法规则

1.XML中有单标记和双标记两种

2.所有标签必须区分大小写

3.所有标签必须符合标签的命名规则

4.实际命名时有较好的阅读习惯

5.所有标签必须合理嵌套

6.所有属性的标签必须使用双引号和单引号括起来

7.XML有且只能有一个根元素

1.3 XML的元素构成

元素的形式

1.空元素

(1)单标记

(2)双标记(不建议使用)

!!如果中间有空格或者换行就说明这个不再是空标记

!!!空元素中也可以包含属性

2.非空元素

(1)带有文本的

(2)带有子元素的元素

(3)同时带有文本的和带有子元素的元素

元素的内容

1.字符数据——不能包含<,>,&

abc

2.字符引用和实体引用——提供了5个预定义的实体引用

3.CDATA段

以字符串<!CDATA[“开始,以字符串”]]> 中间都是包含纯字符数据,但是字符数据可以是不包含CDATA段的结束定界符

在字符数据可以出现的任何地方都可以使用CDATA段

特别是出现特殊字符的时候,就派上用处了

例1-24 XML包含CDATA段

<?xml version="1.0" encoding="UTF-8"?>
<java>
<![CDATA[
if(a<b && c<b)
max=a;
]]>
</java>

4.空白处理

空白包括空格,制表符,空行

只是一个建议。。。

5.行尾处理

6.语言标识

xml:lang来指出XML

<content xml:lang=“en"> This is English

1.4 XML相关技术及不同用途下的类似技术

1.检查XML语义的相关技术

(1) DTD

(2) Schema

2.生成,解析,和检索XML文档的相关技术

(1)DOM

(2)JDOM

(3)DOM4J

(4)SAX

(5)Digester

(6)XQuery

3.显示XML文档的相关技术

(1)CSS

(2)XSLT

4.XML命名空间

习题1答案

  1. 编写一个XML文档

    <?xml version="1.0" encoding="gb2312”?><poem><title>静夜思</title><author>李白</author><content><line>床前明月光</line><line>疑是地上霜</line><line>举头望明月</line><line>低头思故乡</line></content></poem>
    
  2. 判断下列元素的内容是否合法

& 错

/ 对

/> 对

< 错

]]> 错

3.指出下列代码错误

<?xml version="1.0"?><java><![CDTA[    if(array[a[i]]>0){    fun();}    ]]></java>

错误元素中不允许使用]]>

<?xml version="1.0" encoding="UTF-8"?><teams><team><teamid>1</teamid><teamname>北京xx</teamname></team><team><teamid>2</teamid><teamname>大连yy</teamname></team><team><teamid>3</teamid><teamname>上海zz</teamname></team></teams>
  1. XML文件的分类:

无效的XML文档、格式良好的XML文档、有效的XML文档

  1. XML文件的逻辑构成,并简述各部分内容

逻辑构成包括:(1)XML必要声明(2)DTD声明(3)PI(处理指令)(4)元素(5)注释

​ 1) XML必要声明

​ 语法:<? ?>

​ 位置:必须位于第一行

​ 可以包含的属性及含义

​ version 必须的 XML版本 1.0|1.1

​ encoding 可选的 编码方式

​ standalone 可选的 XML文档是否独立 yes|no

2)DTD声明

​ 语法:

​ 内置的DTD声明

  1. PI

​ 语法:<? ?>

​ 位置:通常位于第一个元素之前

​ 如果需要使用的时候给出,否则不写

PI vs xml必要声明的相同点和不同点?

​ (1)位置

​ (2)出现次数

​ (3)作用

4)注释

​ 语法:

​ 需要注意的问题:

​ 1)不能位于必要声明之前

​ 2)不能嵌套在标记中

​ 3)本身不能嵌套

​ 4)中间内容不能出现–

​ 5)不能以—>

5)元素

​ 分类:空元素、带属性的、带内容的、带内容且带属性的

第二章:在XML中使用DTD

2.1 DTD介绍

DTD为XML文档的编写者和提供者提供共同遵守的原则

例2-1:有效的XML文档

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE 根元素名称[<!ELEMENT 根元素名称 (第一个子元素,第二个子元素)><!ELEMENT 第一个子元素 (#PCDATA)><!ELEMENT 第二个子元素 (#PCDATA)><!ATTLIST 第一个子元素 属性一 CDATA #REQUIRED>]><根元素名称><第一个子元素 属性一="任意内容" >文本内容1</第一个子元素><第二个子元素>文本内容2</第二个子元素></根元素名称>

具体约束如下:

(1)XML文档内一共包含三个元素,分别是根元素名称,第一个子元素,第二个元素。

(2)由知道此处根标记为<根元素标记>

(3)由<!ELEMENT 根元素名称 (第一个子元素,第二个子元素)>知道<根元素标记>标记内嵌了两个子标记

(4)<!ELEMENT 第一个子元素 (#PCDATA)>

<!ELEMENT 第二个子元素 (#PCDATA)>知道第一个元素和第二个元素,都是文本内容

(5)DTD在实际应用中的作用如下: 可以验证XML文档大数据的有效性 为某类XML文档提供统一格式和相同的结构

可以保证在一定范围内XML文档的交流和共享 可以让程序设计人员根据DTD可以知道对应的XML文档逻辑结构,从而编写出相应的处理应用程序

DTD基本语法

一个DTD包含对于XML文档使用的元素,元素之间的关系,元素出现的次数,元素中可以使用的属性以及可以使用的实体和符号的定义规则

DTD内部包含下列语句:

(1)元素类型声明语句<!ELEMENT>

(2)属性列表声明<!ATTLIST>

(3)实体声明语句<!ENTITY>

(4)符号声明语句<!NOTATION>

(5)注释语句

DTD被定义为单独文件的例子

<?xml version="1.0" encoding="UTF-8"?><!-- root元素中包含了两个元素--><!ELEMENT root (sub1,sub2)><!ELEMENT sub1 (#PCDATA)><!ELEMENT sub2 (#PCDATA)><!ATTLIST root param1 NOTATION (Jpeg|Png) #REQUIRED               param2 CDATA #IMPLIED><!ENTITY NAME "ENTITY VALUE"><!NOTATION Jpeg SYSTEM "Image/Jpeg"><!NOTATION Png SYSTEM "Image/Png">
<!ELEMENT root (sub1,sub2)> <!ELEMENT sub1 (#PCDATA)> <!ELEMENT sub2 (#PCDATA)> 定义了元素root,sub1,sub2

指明嵌套关系为root内嵌套sub1和sub2两个子元素,这两个子元素是有序的,只出现一次

<!ATTLIST root param1 NOTATION (Jpeg|Png) #REQUIRED param2 CDATA #IMPLIED>属性列表,定义属性为root元素的属性,属性名分别为param1和param2

,需要注意属性是无序的

param1 类型为NOTATION,属性值只能从Jpeg|Png二选一

#REQUIRED表示属性必须的

XML中引用DTD文档

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root SYSTEM "practice.dtd">不仅指出了被引用的DTD文档之外,还指出了文档的根标记是root标记<root param1 ="Jpeg">   <sub1> &NAME;</sub1><sub2>any word</sub2> </root>

*注意使用DTD文档必须使用XML的文档类型声明标记,本例引用的是外部的DTD文档

注意实体引用时,实体名称前面加”&",实体名称后面加";"

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!-- root元素中包含了两个元素--><!ELEMENT root (sub1,sub2)><!ELEMENT sub1 (#PCDATA)><!ELEMENT sub2 (#PCDATA)><!ATTLIST root param1 NOTATION (Jpeg|Png) #REQUIRED               param2 CDATA #IMPLIED><!ENTITY NAME "ENTITY VALUE"><!ENTITY PIC SYSTEM "mspaint.exe">]><root param1="PIC"><sub1>&NAME;</sub1><sub2>any word</sub2></root>

2.1.3引入DTD方式

1.内部DTD

语法格式:

<!DOCTYPE 根元素描述[元素描述]>

2.外部DTD

外部DTD的引用需要事先有一个DYD文件,将DTD约束写入文件中,然后在XML文档中按照以下格式

语法格式描述:

<!DOCTYPE (根元素名称)SYSTEM “外部DTD的URL地址>

SYSTEM关键字表示文档使用是私有的DTD文件,外部DTD的URI可以使相对的也可以是绝对的。外部DTD的URI被称为系统标识符

例子(1)不同位置的多个XML文档要使用同一个DTD文档,可以使用URI来指明DTD文件地址

<!DOCTYPE greeting SYSTEM “http://city.dlut.edu.cn/xml/dtds/hello.dtd">

(2)如果引用DTD的WEB文档与DTD文件在同一个web服务器上,也可以使用相对URI

<!DOCTYPE greeting SYSTEM"/xl/dtds/hello.dtd"><!DOCTYPE greeting SYSTEM"/dtds/hello.dtd"><!DOCTYPE greeting SYSTEM"../hello.dtd"><!DOCTYPE greeting SYSTEM "hello.dtd">

3.公用DTD

语法格式

<!DOCTYPE (根元素名称) PUBLIC "DTD的标识名" "公用DTD的URL地址">

公共DTD要遵守一些约定,如果是“ISO"开头,那么它的名字要以字符串"ISO"开始。标准组织批准的DTD,名字以”+“开始,不是的话以”-“开始

!!前面所提到的,如果文档不依赖于外部文档,在XML声明中可以通过standalone="yes"声明这个文档是独立的文档

当我们使用外部DTD文档时,需要设置standalone=“no”

2.2 DTD中的元素

2.2.1 元素定义语法

具体语法

<!ELEMENT 元素名 元素类型描述>

*元素名:在同一个DTD文件中元素名必须唯一。一旦给一个元素命名,那么在整个文档中大小写都要使用相同的。

*元素类型具体包括

1.字符串类型

2.空元素

3.子元素

4.混合元素

5.任意类型

2.2.2元素类型

1.EMPTY——空元素,

例2-4 空元素的定义

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!--root元素中包含了两个子元素,sub1和sub2都是空元素--><!ELEMENT root (sub1,sub2)><!ELEMENT sub1 EMPTY><!ELEMENT sub2 EMPTY>]><root><!--写法1,不推荐但是写法正确--><sub1></sub1><!--写法2,推荐的正确写法--><sub2/></root>

2.任意元素类型

ANY表示元素的内容为任意类型。

例 2-5 任意内容类型元素的定义

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!--root元素中包含了一个子元素sub1,sub1是任意内容类型元素--><!ELEMENT root (sub1*)><!ELEMENT sub1 ANY><!ELEMENT sub2 EMPTY>]><root><sub1/><sub1>ANY WORD</sub1><sub1><sub2/></sub1><sub1>ANY<sub2/>WORD</sub1></root>

上述的代码sub1 为任意内容类型元素,为空元素,ANY WORD字符串类型元素

子元素类型元素 ANYWORD混合内容类型元素

3.字符串类型

在DTD中可以将所有不包含子标记的元素定义为字符串类型,例如(#PCDATA)

例 2-6 字符串类型元素的定义

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!--root元素中包含了一个子元素sub1,sub1是字符串类型元素--><!ELEMENT root (sub1*)><!ELEMENT sub1 (#PCDATA)><!ELEMENT NAME"ENTITY VALUE">]><root><sub1/><sub1>ANY WORD</sub1><sub1>&NAME;</sub1></root>

字符串内容中包含可解析实体引用也是被允许的

4.子元素

当元素类型定义为子元素时,,必须使用小括号(),元素与元素之间用,隔开表示有序的。元素与元素之间用|隔开表示互斥的

(1)有序子元素,用逗号隔开,表示子元素的出现顺序必须与声明时一致。

<!ELEMENT MYFILE(TITLE,AUTHOR,EMAIL)>表示MYLIFE包括三个子元素,而且必须按顺序出现

(2)无序互斥子元素,用|隔开,表示任选其一

例如<!ELEMENT MYFILE(TITLE|AUTHOR|EMAIL)>表示MYLIFE只能选择其中一个作为MYLIFE子元素

(3)无序组合子元素

+————一次或者多次

?————0次或者一次

*————0次或者多次

省略————一次;

例 2-9 子元素出现的频率示例

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ELEMENT root (sub+,sub2?,sub3*,(sub4,sub5)+)><!ELEMENT sub1 (#PCDATA)><!ELEMENT sub2 (#PCDATA)><!ELEMENT sub3 (#PCDATA)><!ELEMENT sub4 (#PCDATA)><!ELEMENT sub5 (#PCDATA)>]><root> <sub1>sub11</sub1><sub2>sub22</sub2><sub4>sub4</sub4><sub5>sub5</sub5><sub4>sub4</sub4><sub5>sub5</sub5></root>

还可以写无序组合子元素

<!ELEMNT sub5(sub6|sub7)> 表示元素sub5包含sub6和sub7,这两个元素即可以单独出现也可以同时出现,出现次数和顺序没有限制

5.混合类型

混合类型定义的子元素即可以包含字符串也可以包含子元素,定义方法:

<!ELEMENT root(#PCDATA|sub1|sub2)*>

不建议使用。。。

2.3 DTD中的属性

在DTD中声明元素属性的语法:

<!ATTLIST 元素名        [属性名1 属性类型  [约束] [默认值]]        [属性名2 属性类型  [约束] [默认值]]        >

说明:
在一个ATTLIST 中可以定义同一个元素下的一个或多个属性。如果包含多个属性声明,属性声明之间使用空格间隔。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1NwhWyx5-1631502088719)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210527135805936.png)]

默认值:只有当约束为#FIXED时,才能给默认值

例 2-12 属性定义的示例代码

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ELEMENT (#PCDATA)><!ATTLIST root reqParam CDATA #REQUIRED><!ATTLIST root impParam CDATA #IMPLIED>                fixParam CDATA #FIXED "default value">                  ]><root reqParam="required value></root>

属性类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ekRrsoAe-1631502088721)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210527140444653.png)]

(1)CDATA类型

要求属性必须是字符数据类型

例 2-13 CDATA类型属性代码

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ELEMENT root (book+)><!ELEMENT book (#PCDATA)><!ATTLIST book description CDATA #REQUIRED>]><root><book description="一本经典书">JAVA</book><book description="">JSP</book></root>

(2)ID IDREF IDRFS类型

ID类型要求属性的属性值是唯一的,特别注意,属性值要去必须以字母开头,而且必须是有效的XML标识符

IDREF类型要求属性值必须是一个已经存在的ID类型值

IDRFS类型表示属性值可以引用多个已经存在ID类型值,中间用空格间隔

例 2-14 ID IDREF IDREFS类型属性代码

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ELEMENT root (book+,person+)><!ELEMENT book (#PCDATA)><!ELEMENT person (#PCDATA)><!ATTLIST book id ID #REQUIRED                borrowed IDREFS #REQUIRED><!ATTLIST person num ID #REQUIRED            borrow IDREF #REQUIRED>                  ]><root><book id="a01" borrowed="s01 s02">JAVA 编程</book><book id="a02" borrowed="s03">JSP编程</book><person num="s01" borrow="a01">张三</person><person num="s02" borrow="a01">李四</person><person num="s03" borrow="a02">王五</person></root>

(3)Enumerated类型

枚举类型

例2-15 枚举类型属性代码

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ELEMENT root (#PCDATA)><!ATTLIST root day (周一|周二|周三|周四|周五|周六|周天) #REQUIRED>]><root day="周一"></root>

必须从七个属性值里面选择一个作为实际的属性值

(4)NMTOKEN和NMTOKNS类型

NMTOKEN属性值只能由字母,数字,下划线,英文的画线,英文点,英文冒号

而且是预先定义好的

Enumerated只能在诸多技能中,选择写出了一个属性值。将技能定义为NMTOKENS类型,最擅长的技能定义为NMTOKEN类型

例 2-16 NMTOKEN和NMTOKNS类型

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ELEMENT root (person+)><!ELEMENT person (#PCDATA)><!ATTLIST person skills NMTOKENS #REQUIRED                bestskill NMTOKEN #REQUIRED>]><root><person skills="游戏" bestskill="游戏">张三</person>  <person skills="java c php" bestskill="c">张三</person>  </root>

(5)ENTITY,ENTITIES和NOTAION类型

ENTITY类型:表示该属性值为未解析的外部实体

ENTITIES类型:表示该属性值为多个未解析的外部实体

NOTAION类型、、、、不推荐使用

2.4 DTD中的实体和符号

1.实体:按照使用方式划分为普通实体和参数实体

普通实体划分为内部实体和外部实体

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y3JOgTpf-1631502088723)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210527151055856.png)]

(1)通用内部解析实体

语法格式:

<!ENTITY 实体名称 "实体内容">

内部实体可以在XML文档中进行引用

语法格式:&实体名称;

例2-17

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE aa[<!ELEMENT aa(#PCDATA)><!ENTITY copyright"&lt;aa&gt;是根标记">]><aa>&copyright;</aa>

在实体中可以嵌套调用,但是不能两个实体互相嵌套调用,会有死循环

<!ENTITY one "one"><!ENTITY two "&one;i am two">

(2)通用外部解析实体

引用外部的一个文件,被引用的实体必须是可解析的,扩展名没有限制

语法如下

<!ENETITY 实体名称 SYSTEM|PUBLIC["公共实体标识符"]“URI/URL">

例2-18

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE aa[<!ELEMENT aa(#PCDATA)><!ENTITY copyright SYSTEM"other.text">]><aa>&copyright;</aa>

(3)通用外部未解析实体

语法格式如下

<!ENETITY 实体名称 SYSTEM“URI/URL" NDATA 标记名>

外部解析实体只能在外部DTD文件中定义,实体只能定义为ENTITIES或者ETITY类型

例2-19外部DTD文件

<?xml version="1.0" encoding="UTF-8"?><!ELEMENT aa (#PCDATA)><!ENTITY PICTURE SYSTEM "pic.jpg" NDATA msp><!ENTITY PICTURE SYSTEM "pic1.jpg" NDATA msp><!ENTITY PICTURE SYSTEM "pic2.jpg" NDATA msp><!NOTATION msp SYSTEM "mspaint.exe"><!ATTLIST aa bgImage ENTITY #REQUIRED             backImages ENTITIES #REQUIRED>

上述代码,aa元素包含了两个属性,bgImage属性被定义为ENTITY ,该属性的属性值是一个外部未解析实体的名称。

bgImages属性被定义为ENTITIES ,该属性的属性值是一个或多个外部未解析实体的名称。

在DTD定义了三个外部未解析实体PICTURE,PICTURE1,PICTURE2

例子 2-20 XML文件源代码

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE aa SYSTEM "outerunparseenity.dtd"><aa bgImage="PICTURE" backImages="PICTURE1 PICTURE2"></aa>

(4)参数内部解析实体

语法格式

<!ENTITY %参数实体名称 “实体内容”>

引用实体的语法如下:

%参数实体名称;

例 2-21 内部参数解析实体

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!--使用参数实体声明--><!ENTITY % shopattr "<!ELEMENT name (#PCDATA)><!ELEMENT address(#PCDATA)><!ELEMENT size(#PCDATA)>"><!ELEMENT root (shop)+><!ELEMENT shop (name,address,size)><!--参数实体引用-->%shopattr;]><root><shop><name>物美</name><address>文一路</address><size>旗舰店</size></shop></root>

(5)参数外部解析实体

<!ENTITY %参数实体名称 SYSTEM"URI/URL">

引用参数实体的语法

%参数实体名称;

通过参数外部解析实体可以实现DTD文件的复用

<?xml version="1.0" encoding="UTF-8"?><!ELEMENT A(NAME_A)><!ELEMENT NAME_A(#PCDATA)>

上述DTD定义了两个元素,分别是A和NAME_A

<?xml version="1.0" encoding="UTF-8"?><!ELEMENT B(NAME_B)><!ELEMENT NAME_B(#PCDATA)>

上述DTD定义了两个元素,分别是B和NAME_B

例2-23文件内置的DTD通过外部解析参数实体复用上述A.dtd和B.dtd

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE ROOT[<!ELEMENT ROOT (A|B)*><!ENTITY % A_attr SYSTEM "A.dtd"><!ENTITY % B_attr SYSTEM "B.dtd">%A_attr;%B_attr;]><ROOT><A><NAME_A>i am A</NAME_A><B><NAME_B>i am A</NAME_B></B></ROOT>

2.符号

语法格式:

<!NOTATION 符号名称 SYSTE|PUBLIC["公共符号标识符"]“URI/URL">

2.5 使用XMLSpy做DTD与XML转换

2.5.1 根据XML文件产生DTD
(1)在XMLSpy中打开XML文件。
(2)选择DTD/Schema中的Generate DTD/Schema命令,弹出对话框。
(3)在对话框中默认选择转换为DTD文件,单击OK按钮,弹出另存对话框。
(4)在另存为对话框中选择正确路径,输入DTD文件名,保存。
(5)弹出对话框中添加文档类型声明引用生成的DTD。
2.5.2根据DTD文件产生XML
(1)在XMLSpy中打开DTD文件。
(2)选择DTD/Schema中的Generate Simple XML File命令,弹出对话框。
(3)在对话框中允许用户选择XML文件类型,默认选项,OK。即可生成XML文件模板。

2.6 DTD的优缺点

DTD采用非XML语法描述语义约束,可实现功能:
XML文档带有自身格式描述。
企业可以有标准的DTD交换数据。
应用程序可使用标准DTD验证XML文档。
开发者使用DTD验证XML文档。

DTD自身问题:
基于正则表达式,描述能力较弱。
不支持数据类型,数据约束不准确。
约束能力不足,无法更精细的语义限制。
结构不够好,可重用性差。

第三章:命名空间

3.1 命名空间的概述

在XML文件中会经常出现元素同名但是含义不同的情况,这个时候XML处理器无法区分他们,会造成含义不清。

例如 3-1 XML文件同名不同义的标记

<?xml version="1.0" encoding="UTF-8"?> <book><name>XML技术应用</name><author><name>余可</name><age>19</age></author></book>

例如 3-2 利用命名空间解决同名问题

<?xml version="1.0" encoding="UTF-8"?><book xmlns:bk="http://www.dlut.edu.cn/xml/book"xmlns:au="http://www.dlut.edu.cn/xml/author"><bk:name>XML技术应用</bk:name><author>余可</author><age>19</age></book>

命名空间语法: xmlns[:prefix]=“命名空间字符串”

命名空间字符串是一个URI,可以不是真实的,只要唯一性就可以。

prefix:表示前缀名称,可以随意指定

命名空间包括两种形式

(1)没有前缀限定的命名空间

例3-3

<?xml version="1.0" encoding="UTF-8"?><root xmlns="http://www.dlut.cn/xml/namespace">	<sub>abc</sub>	</root>

!当XML文档中所有元素或者大部分位于某个命名空间下,可以使用这个方式简化编写。

(2)有前缀限定的命名空间

有前缀限定的命名空间可以使用多个,但是命名空间的别名必须不同。

例3-4 有前缀限定的命名空间

<?xml version="1.0" encoding="UTF-8"?><dlut:root xmlns:dlut="http://www.dlut.cn/xml/namespace">	<dlut:sub>abc</dlut:sub>	<dlut:/root>

例3-5 多个命名空间声明

<?xml version="1.0" encoding="UTF-8"?><dlut:root xmlns:dlut="http://www.dlut.cn/xml/dlut" xmlnsxmlns:city="http://www.dlut.edu.cn/xml/city"            xmlns="http://www.dlut.edu.cn/xml/namespace">	<sub>abc</sub>    <city:sub2>abc</city:sub2>	<dlut:/root>

上述代码有三个命名空间:<dlut:root xmlns:dlut=“http://www.dlut.cn/xml/dlut” xmlnsxmlns:city=“http://www.dlut.edu.cn/xml/city”
xmlns=“http://www.dlut.edu.cn/xml/namespace”>

分别是dlut,city和默认的别名

!在声明命名空间还有一种特殊的写法,即命名空间的别名为空,命名空间的URI也是空,例如表示默认的命名空间不在任何命名空间中,与表达含义相同。

!避免在元素中声明的命名空间相同,只是命名空间的别名不同,则不同别名指定的仍是同一个命名空间。

例3-6 相同命名空间多次声明

<?xml version="1.0" encoding="UTF-8"?><book xmlns:bk="http://www.dlutedu.cn/book" xmlnsxmlns:book="http://www.dlut.edu.cn/xml/book" ><bk:name>XML应用技术</bk:name><book:ISBN>ISBN1654</book:ISBN></book>

3.2 命名空间作用域

例 3-7 命名空间作用范围

<?xml version="1.0" encoding="UTF-8"?><book><bk:name xmlns:bk="http://www.dlut.edu.cn/xml/book">XML应用技术</bk:name><author>余可哈哈哈哈哈哈</author></book>

上述在name元素中声明了命名空间,该命名空间只能在该元素及其子标记中使用

例 3-8 修改命名空间声明位置

<?xml version="1.0" encoding="UTF-8"?><book xmlns:bk="http://www.dlut.edu.cn/xml/book"><bk:name >XML应用技术</bk:name><author>余可哈哈哈哈哈哈</author></book>

修改后该命名空间位于根元素book上,该命名空间的作用范围为该文件所有文件,即该文件中所有标记都可以使用该命名空间

!如果该命名空间被子元素同别名的命名空间伏盖,则该命名空间无法作用于于子元素

例 3-9命名空间覆盖

<?xml version="1.0" encoding="UTF-8"?><book xmlns:bk="http://www.dlut.edu.cn/xml/book"><bk:name >XML应用技术</bk:name><author xmlns:bk="http://www.dlut.edu.cn/xml/author">余可哈哈哈哈哈哈</author></book>

子元素author又声明了命名空间,采用了相同的别名,则book中声明的命名空间无法作用于author元素及其子元素

同样,author元素及其子元素如果使用命名空间的话,只能使用http://www.dlut.edu.cn/xml/author

3.3 元素对命名空间的使用

命名空间可以作用于相应的元素,但是并不代表钙元素位于声明的命名空间中。如果要表示某元素位于某命名空间,需要要将所有

元素改为该命名空间的元素。

例 3-10 元素对命名空间的使用

<?xml version="1.0" encoding="UTF-8"?><book xmlns:bk="http://www.dut.edu.cn/xml/book"><bk:name>XML教程</bk:name><author>余大可哈哈哈哈</author></book>

!命名空间可以作用于所有元素,但属于该命名空间的元素只有name!!!,其他元素度没有位于任何命名空间中

例 3-11 修改后元素对命名空间的使用

<?xml version="1.0" encoding="UTF-8"?><book xmlns:bk="http://www.dut.edu.cn/xml/book"><bk:name>XML教程</bk:name><bk:author>余大可哈哈哈哈</bk:author></book>

!修改后,所有元素都属于该命名空间。

例 3-12 修改后元素对默认命名空间的使用

<?xml version="1.0" encoding="UTF-8"?><book xmlns:bk="http://www.dut.edu.cn/xml/book"><name>XML教程</name><author>余大可哈哈哈哈</author></book>

!修改后,利用默认命名空间,使所有元素都属于该命名空间。代码繁琐度降低

例 3-13不同元素对多个命名空间的使用

<?xml version="1.0" encoding="UTF-8"?><book xmnls:bk="http://www.dlut.edu.com.cn/xml/book"xmlns:au="http://www.dlut.edu.com.cn/xml/author"xmlns:bk="http://www.dlut.edu.com.cn/xml">	<bk:name>XML应用技术</bk:name>	<author>		<au:name>余大可</au:name>		<age xmlns="">18</age>	</author></book>	

!XML文件声明了三个命名空间

bk:name属于book xmnls:bk="http://www.dlut.edu.com.cn/xml/book"命名空间

au:name属于book xmnls:bk="http://www.dlut.edu.com.cn/xml/author"命名空间

au:name属于book xmnls:bk="http://www.dlut.edu.com.cn/xml"命名空间

在有一次声明了默认命名空间,而且URI值为空字符串,表示元素不属于人任何命名空间

3.4 属性对命名空间的使用

如果在属性上没有使用任何命名空间别名,则表示该属性不属于任何命名空间

注意:属性的命名空间是独立的,即无论属性所属的元素属于任何命名空间都与属性的命名空间无关。

例 3-14 属性对于命名空间的使用

<?xml version="1.0" encoding="UTF-8"?><book xmlns:au="http://www.dut.edu.cn/xml/author"xmlns="http://www.dlut.edu.cn/xml"><name>XML技术</name><author au:id="x001" birthday="20010529"><name>余大可</name><age>19</age></author></book>

!属性id属于前缀au的命名空间,但是属性birthday不属于任何命名空间

默认名称空间有效范围

(1)若为某元素声明了名称空间,则,该元素及其子元素(包括属性)均隶属于该名称空间,除非他们又受到其他名称空间的限制

(2)若一个元素声明了默认名称空间,该元素的子元素还可以声明其他默认名称空间。

(3)如果一个默认名称空间URI属性值为空则该元素不隶属于任何名称空间内。即可通过将默认名称空间赋值为空字符串,取消默认的名称空间。

3.5DTD对命名空间的使用

DTD出现早于命名空间,可以说DTD不支持命名空间

例 3-15 DTD不支持声明了命名空间的XML文件

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE book[<!ELEMENT book (name,author)><!ELEMENT name (#PCDATA)><!ELEMENT author (name,age)><!ELEMENT age (#PCDATA)>]><book xmlns:bk="http://www.dut.edu.cn/xml/book"xmlns:au="http://www.dlut.edu.cn/xml/author"xmln="http://www.dlut.edu.cn/xml"><name>XML技术</name><author><name>余大可</name><age>19</age></author></book>

结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0BfIWoj3-1631502088724)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210517195145961.png)]

例3-16 使用命名空间的XML文件

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE book[<!ELEMENT book (bk:name,author)><!ELEMENT bk:name (#PCDATA)><!ELEMENT author (au:name,age)><!ELEMENT au:name (#PCDATA)><!ELEMENT age (#PCDATA)><!ATTLIST book xmlns:bk CDATA #IMPLIEDxmlns:au CDATA #IMPLIEDxmln CDATA #IMPLIED><!ATTLIST age xmln CDATA #IMPLIED>]><book xmlns:bk="http://www.dut.edu.cn/xml/book"xmlns:au="http://www.dlut.edu.cn/xml/author"xmln="http://www.dlut.edu.cn/xml"><bk:name>XML技术</bk:name><author><au:name>余大可</au:name><age xmln="">19</age></author></book>

!如果命名空间别名在XML中做了修改,那么DTD中对应约束也要。

课后习题

习题3答案

修改XML文件,要求标记的及其子标记位于命名空间http://www.dlut.du.cn/xml/major下

及其子标记和位于命名空间http://www.dlut.du.cn/xml/student下,其余标记默认在http://www.dlut.du.cn/xml下

代码如下

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE class [<!ELEMENT class (aa:major,students)*><!ELEMENT aa:major (aa:name)*><!ELEMENT aa:name (#PCDATA)><!ELEMENT students (bb:student)*><!ELEMENT bb:student (bb:name+,bb:age+)><!ELEMENT bb:name (#PCDATA)><!ELEMENT bb:age (#PCDATA)><!ATTLIST class xmlns:aa CDATA #REQUIREDxmlns:bb CDATA #REQUIREDxmlns CDATA #REQUIRED><!ATTLIST bb:studentsn CDATA #REQUIRED>]><class xmlns:aa="http://www.dlut.edu.cn/xml/major" xmlns:bb="http://www.dlut.edu.cn/xml/student" xmlns="http://www.dlut.edu.cn/xml"><aa:major>	<aa:name>软件工程</aa:name></aa:major><students>	<bb:student sn="01">		<bb:name>张三</bb:name>		<bb:age>18</bb:age>	</bb:student>	<bb:student sn="02">		<bb:name>李四</bb:name>		<bb:age>120</bb:age>	</bb:student></students></class>

2.标记的bookid属性位于命名空间http://www.dlut.edu.cn/xml/book下,标记的name属性位于命名空间http://www.dlut.edu.cn/xml/rcord下

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE library [<!ELEMENT library (books,records)*><!ELEMENT books (book*)><!ELEMENT book (#PCDATA)><!ATTLIST book aa:bookid CDATA #REQUIRED><!ELEMENT records (item*)><!ELEMENT item (date+,person+)><!ELEMENT date (#PCDATA)><!ELEMENT person (#PCDATA)><!ATTLIST person bb:name CDATA #REQUIRED><!ATTLIST person borrowed CDATA #REQUIRED><!ATTLIST library xmlns:aa CDATA #REQUIREDxmlns:bb CDATA #REQUIRED> ]><library xmlns:aa="http://www.dlut.edu.cn/xml/book"xmlns:bb="http://www.dlut.edu.cn/xml/record"><books><book aa:bookid="b-1-1">XML详解</book><book aa:bookid="b-1-2">Servlet从入门到精通</book><book aa:bookid="b-1-3">JSP实例编程</book></books><records><item><date>2012-08-01</date><person bb:name="张三" borrowed="b-1-1 b-1-2"/></item><item><date>2012-08-02</date><person bb:name="李四" borrowed="b-1-1 b-1-3"/></item></records></library>

第四章:在XML中使用Schema

4.1 Schema概述

Schema基础知识

优势

(1)更加完善,更加强大

(2)基于XML编写

(3)支持数据类型

(4)支持命名空间

第一个Schema文件 例4-1

<?xml version="1.0" encoding="UTF-8"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:element name="school"><xs:complexType><xs:sequence><xs:element name="name" type="xs:string"/><xs:element name="major" type="xs:string" minOccurs="1" maxOccurs="unbounded"/></xs:sequence></xs:complexType></xs:element></xs:schema>

Schema本身也是一个XML文档

(1)<xs:schema xmlns:xs=“http://www.w3.org/2001/XMLSchema”>——引入命名空间

(2)< xs:complexType…>——表示定义了复杂类型元素(所谓复杂元素类型是指元素包含子元素,属性,或者既包含子元素又包含属性)

(3)minOccurs=“1”——表示至少出现了一次 maxOccurs=“unbounded”——表示最多出现次数没有限制

例4-2 引用first.xsd作为语义约束的XML文件

<?xml version="1.0" encoding="UTF-8"?><school xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="first.xsd"><name>计算机学院</name><major>软件工程</major><major>计算机科学</major></school>

4.2 Schema的引用方法

有两种方式引入:(1)不属于特定空间的

1.通过xsi:noNamespaceSchemLocation引入

具体语法:

<根元素名称 xmlns :xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="XML.Schemna">

xsi:noNamespaceSchemaLocation属性值为一个Schema文件的URI。该属性值只能是一个Schema文件URI,即只能使用一个Schema文件,

2.通过xsi:NamespaceSchemLocation引入

如果被引入的Schema文件需要约束XML文件属于某个特定的命名空间元素,则通过xsi:schemaLocation属性引入

具体语法:

<根元素名称[ xmlns :命名空间别名=“命名空间URI"]+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="[命名空间URI Schema文件路径]+">

+xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” 这样属性值较为灵活,可以同时引入多个Schema文件

命名空间URI和Schema文件路径中间使用空格间隔

例 4-3 约束命名空间http://www.dlut.edu.cn/xml的Schema文件firsttarget.xsd

<?xml version="1.0" encoding="UTF-8"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"targetNamespace="http://www.dlut.edu.cn/xml" xmlns:c="http://www.dlut.edu.cn/xml"><xs:element name="collage"><xs:complexType><xs:sequence><xs:element ref="c:name"></xs:element><xs:element ref="c:major" minOccurs="1" maxOccurs="unbounded"></xs:element></xs:sequence></xs:complexType></xs:element><xs:element name ="name" type="xs:string"/><xs:element name ="major" type="xs:string"/></xs:schema>

上述代码定义了三个元素,都属于命名空间http://www.dlut.edu.cn/xml

名称为collage,name,major 而且collage元素包含两个有序的子元素,即name,major

引用Schema文件的XML文件如下

例4-4引用Schema文件的XML文件

<?xml version="1.0" encoding="UTF-8"?><s:collage xmlns:s="http://www.dlut.edu.cn/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.dlut.edu.cn/xml firsttarget.xsd"><s:name>计算机学院</s:name><s:major>软件工程</s:major><s:major>计算机科学</s:major><s:major>嵌入式</s:major></s:collage>

上述代码引用firsttarget.xsd文件作为当前XML文件的语义约束

4.3 Schema的语法结构

XML Schema是扩展名为".xsd"的文本文件,使用XML语法编写,基本语法结构如下

<?xml version="1.0" encoding="gb2312"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">...[元素、属性、注释、数据类型、schema的复用]</xs:schema>

XMLSchema文档是基于XML文档语法法规范编写,根标记必须为Schema xmlns:xs="http://www.w3.org/2001/XMLSchema"属性制定了XML文档实验的命名空间,这个也是W3C的命名空间

用户还可以为该元素指定两个属性

(1)elmentFormDefault:该属性值可以是qualified或unqualified,用于指定Schema中定义的局部元素是否必须使用命名空间限定,属性默认值是qualified

(2)attributeFormDefault:该属性值可以是qualified或unqualified,用于指定Schema中定义的局部元素是否必须使用命名空间限定,属性默认值是unqualified

4.3.1元素

在Scheam中定义及引用元素的语法主要包括以下三类

语法一

<xs:element name="元素名称" type="数据类型"[default="默认值"][inOccurs="最少出现的次数"][minOccurs="最多出现的次数"]/>

语法二

 <xs:element name="元素名称" [default="默认值"][inOccurs="最少出现的次数"][minOccurs="最多出现的次数"]>     Element type</xs:element>

语法三

 <xs:element ref="引用元素名称"[default="默认值"][inOccurs="最少出现的次数"][minOccurs="最多出现的次数"]/>

name:元素的名称,自己定义

type:元素的数据类型

default:元素的默认值

minOccurs:指定该元素最少出现次数,默认值为1,如果minOccurs和maxOccurs没有同时出现,则该属性值只能为1或者0

maxOccurs:指定该元素最大出现次数,默认值为1,如果指定该元素可以默认出现多次,那么属性值为"unbounded",如果minOccurs和maxOccurs同时出现,则该属性值不能为1

元素按照复杂程度可以划分:简单元素:不包含属性和子元素

复杂元素:可以包含属性和子元素

例4-5 Schema文件关于元素的定义elementDemo.xsd

<?xml version="1.0" encoding="UTF-8"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"attributeFormDefault="unqualified"><!--语法2定义复杂元素root--><xs:element name="root"><xs:complexType><xs:sequence><!--语法1定义简单元素sub1--><xs:element name="sub1" type="xs:string" default="sub1content"/><!--语法3引用通过下面的语法1定义元素sub2--><xs:element ref="sub2" minOccurs="1" maxOccurs="unbounded"/></xs:sequence></xs:complexType></xs:element><!--语法1定义简单元素sub2--><xs:element name="sub2" type="xs:string"/></xs:schema>

元素按照定义位置还可以划分:全局元素:可以在root元素中引用该元素

局部元素:无法被其他元素引用

例如sub1就是局部元素,无法被其他元素引用

但是root和sub2是全局元素,在root元素可以引用该元素

例4-6 符合elementDemo.xsd约束的XML文件

<?xml version="1.0" encoding="UTF-8"?><root xsi:noNamespaceSchemaLocation="elementDemo.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><sub1>sub1content</sub1>	<sub2>String</sub2></root>

元素组是把多个元素及其约束组合在一起,使用时作为一个整体

元素组可以更好地实现复用,用户可以定义元素组

定义元素组语法:

<xs:group name ="元素组名称">包含多个元素及其约束</xs:group>

引用元素组语法:

<xs:group ref="元素组名称"/>

例4-7 Schema文件关于元素组的定义和使用

<?xml version="1.0" encoding="UTF-8"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"attributeFormDefault="unqualified"><xs:element name="root"><xs:complexType><xs:sequence><xs:element name="main1"><xs:complexType><xs:group ref="subgroup"/></xs:complexType></xs:element><xs:element name="main2"><xs:complexType></xs:complexType></xs:element></xs:sequence></xs:complexType></xs:element><xs:element name="sub2" type="xs:string"/><xs:group name="subgroup"><xs:sequence><xs:element name="sub1" type="xs:string" default="sub1content"/><xs:element ref="sub2" minOccurs="1" maxOccurs="unbounded"/></xs:sequence></xs:group></xs:schema>

定义元素组的代码如下:<xs:group name=“subgroup”>
xs:sequence
<xs:element name=“sub1” type=“xs:string” default=“sub1content”/>
<xs:element ref=“sub2” minOccurs=“1” maxOccurs=“unbounded”/>
</xs:sequence>
</xs:group>

4.3.2 属性

定义属性的语法格式如下

(1)语法一:定义新属性的语法

<xs:attribute name="属性名" type="属性类型" [default="默认值"]|[fixed="固定值"]>

(2)语法二:属性的引用,引用之前必须用语法一定义

<xs:attribute ref="属性名"></xs:attribute>

default:属性默认值,可选(不与fixed同时存在)

fixed:属性的固定值,若该属性存在则该属性固定(不与default同时存在)

例4-9 schema中关于属性的定义以及使用

<?xml version="1.0" encoding="UTF-8"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"attributeFormDefault="unqualified"><!--语法1定义属性名为id--><xs:attribute name="id" type="xs:string"/><xs:element name="root"><xs:complexType><xs:sequence><xs:element name="sub" type="xs:string"/></xs:sequence><!--语法1定义属性名为name--><xs:attribute name="name" type="xs:string" use="optional"/><!--语法2定义好的属性名id--><xs:attribute ref="id" use="required"/></xs:complexType></xs:element></xs:schema>

在上述代码中,引用了三处xs:attribute来定义属性

(1)语法一使用<xs:attribute name=“id” type=“xs:string”></xs:attribute>属性名为id,属性类型为字符串类型

(2)语法二使用<xs:attribute ref=“id” use=“required”/>引用已经定义好的属性,该属性名为id,属性在当前元素中必须是给出的属性

例子4-10 符合上面schema文件约束的XML文件

<?xml version="1.0" encoding="UTF-8"?><root id="String" name="namestr" xsi:noNamespaceSchemaLocation="attDemo.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><sub>String</sub></root>

属性可以定义为全局属性和局部属性,在Schema元素中定义的为全局元素

在复杂类型中定义的为局部元素

属性组的语法如下

<xs:attributeGroup name="属性组名称">包含多个属性</xs:attributeGroup>

例子 4-11 属性组的定义和使用

<?xml version="1.0" encoding="UTF-8"?><xs:schema xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributedFormDefault="unqualified"><xs:element name="root"><xs:complexType><xs:sequence><xs:element name="sub1" type="xs:string" default="sub1content"/><xs:element ref="sub2" minOccurs="1" maxOccurs="unbounded"/></xs:sequence><!--属性组的引用--><xs:attributedGroup ref="attlist"/></xs:complexType></xs:element><xs:element name="sub2" type="xs:string"/><!--属性组的定义--><xs:attrubuteGroup name="attlist"><xs:attribute name="id" type="xs:string"/><xs:attribute name="language" tpe="xs:string" default="java"/></xs:attrubuteGroup></xs:schema>

符合上述的生成的XML文件

<?xml version="1.0" encoding="UTF-8"?><root xsi:noNamespaceSchemaLocation="attlistGroupDemo.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id=::"idStr" languagee="xml"><sub1>sub1content</sub1>    <sub2>String</sub2></root>

4.3.3 注释

有两种方法:(1) (2)通过标记增加注释,这种方式有更好地可读性!

对于的

说明(1)通常放在Schema组件定义开始的部分,用于说明该Schema组件的作用。内部可以出现多个<documentation…/>和<appinf…/>而且出现的顺序和次数都没有限制

(2)该元素的注释主要供人阅读

(3)该子元素的注释主要供其他程序使用

<?xml vesion"1.0" encoding="UTF-8"?><xs:schema xmlns:xs="http://www.w3.org.2001/XLSchema"           targetNamespace="http://www.dlut.edu.cn/xml"><xs:annotaion>    <xs:documentation>该标记作为XML文件根标记实验</xs:documentation>    </xs:annotaion><xs:element name="collage">    <xs:complexType>    <xs:sequnce>        <xs:annotation>        <xs:ducumentation>子标记name</xs:ducumentation>        <xs:ducumentation>子标记major</xs:ducumentation>        <xs:appinfo>string</xs:appinfo>        </xs:annotaation>        <xs:element name="name" type="xs:string"/>        <xs:element name="major" type="xs:string" minOccurs="1" maxOccur="unbounded">                </xs:element>        </xs:sequnce>    </xs:complexType>     </xs:element></xs:schema>

Schema的数据类型

按照扩展方式分为(1)内置数据类型:schema规范中已经定义好的类型,用户可以直接使用,所有内置类型除anyType之外都是简单类型,有三种类型1.任意类型 2.内置基本数据类型 3.内置扩展数据类型

(2)用户自定义数据类型:用户既可以自定义基本数据类型,也可以自定义复杂数据类型,所有的复杂数据类型都必须用户自定义得到

!!!关于elementFormDefault意思是这样的:

1、在xml中,所有引用xsd的全局的元素都必须加上命名空间的前缀

(例如xmlns:aa=http://www.example.org/classroom,全局元素都得加上aa)。

2、非全局的元素当设置为qualified时,必须添加命名空间的前缀。

3、非全局的元素当设置为unqualified时,不必也不能添加前缀。

下面是一个简单的例子:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gT15xRRt-1631502088726)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210522130247930.png)]

a. 当设置为unqualified时,user为全局元素(可作为根元素)必须添加前缀,非全局元素

(id,name)不必添加前缀。

b. 当设置为qualified时,所有的元素都必须添加前缀。

!!!关于attributeFormDefault

attributeFormDefault=‘unqualified’ 时表示目标命名空间下的这个属性不要带命名空间前缀.

attributeFormDefault=‘qualified’ 时表示来自目标命名空间下的属性必须要用命名空间前缀修饰.

4.4 Schema的数据类型

4.4.1内置数据类型

1.任意类型

任意类型包括anyType和anysmpleType两种

anyTyp e——该元素为任意类型,和DTD中的ANY类似,此类型对元素的类型没有任何约束

anysmpleType——表示该元素为任意简单类型,定义为该类型

2.内置基本数据类型

3.内置扩展数据类型

4.4.2用户自定义数据类型

1.自定义简单数据类型

2.自定义复杂数据类型

第五章:Schema高级技术

5.1 Schema的高级特性

5.2 Schema的复用

5.3 Schema实践技巧——空元素的表示

第六章:XML显示技术之CSS

6.1 XML的显示技术、

主要有CSS,XSL,XML数据岛,JAVAScript

CSS就是层叠样式表,也被翻译为级联样式表,对页面的布局,字体,颜色,背景等效果进行精确

6.2 在XML中引入CSS

1.在XML引用外部的CSS文件

具体语法格式

<?xml-stylesheet type="text/css" href="被引用的外部的CSS文件URI"?>

type:如果引用的是CSS文件,那么该属性值必须为“text/css"

href:指定被引入的外部CSS文件到的URI

例6-1

<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/css" href="demo.css"?><person><name>田诗琪</name><birthdate>2001-05-29</birthdate><sex></sex><high>166cm</high></person>

被引用的CSS样式见下

name{display:block;font-size:28px;text-align:center;}

2.在XML中使用内嵌的CSS样式

需要使用以下标记

<HTML:style xmlns:HTML="http://www.w3.org/1999/xhtml">CSS样式代码</HTML>

例子 6-3

<?xml version="1.0" encoding="UTF-8"?><book-info><HTML:style xmlns:HTML="http://www.w3.org/1999/xhtml">book-info{display:block;}book{display:block;}title{display:block;font-family:黑体;font-size:20pt;color:#0000FF;text-align:center;}type{display:block;font-family:仿宋;text-align :center;}author{display:block ;font-family:仿宋;text-align:center;}</HTML:style><book><title>计算机网络</title><type>计算机</type><author>谢希仁</author></book><book><title>西游记</title><type>文学</type><author>吴承恩</author></book>

6.3 CSS的基本语法

由三个部分组成:选择器,样式属性,样式属性取值

具体语法格式如下

selector{property1:value1;property2:value2;....}

selector:选择器,被施加样式的元素,可以使用标记tag,类名class,标识名id。。。

property:样式属性,可以使用颜色,字体,背景等

value:样式属性取值

以下为CSS一个选择器到的定义代码

name{display:block;font-size:28px;text-align:center;}

书上给出了很多属性

CSS单位

(1)相对长度单位:em ex px %

(2)绝对长度单位: in cm mm pt pc

颜色单位RGB 十六进制

CSS选择器

1.Selector{…}:该选择器对元素名为Selector起作用,当多个元素显示效果相同的时候,多个选择器可以合并写为Selector1,Selector2的形式{…},

2.Selector[attr]{…}:该选择器对元素名为Selector起作用,并且包含属性attr的值的元素起作用

3.Selector[attr=value]{…}:该选择器对元素名为Selector起作用,并且对属性attr的值为value的元素起作用

4.Selector[sttr~=value]{…}:该选择器对元素名为Selector起作用,并且对属性attr的多个值中间使用空格间隔,其中一个值为value的元素起作用

5.Selector[attr|=value]{…}:该选择器对元素名为Selector起作用,并且对属性attr的多个值中间使用|隔开,其中一个值为value的元素起作用

第七章:Xpath

7.1 XPath概述

由W3C指定的,在XML文档进行寻址的表达式语言

包括以下三个部分:

(1)XPath使用路径表单上在XML文档中进行导航

(2)XPath包含一个标准数据库

(3)XPath是XSLT中主要元素

目前XPath版本有1.0 2.0 3.0

7.2XPath结点

XML文档一共包含了7种类型结点

  1. 根结点

  2. 元素结点

  3. 属性结点

  4. 文本结点

  5. 命名空间结点

  6. 处理指令结点

  7. 注释结点

7.3XPath路径

XPath由一个或者多个STEP组成 ,不同的Step由 / 隔开

完整语法:

轴 ::结点测试 [限定谓语]例如: child ::id[text( )=100]

轴:定义当前结点和所选结点的关系

结点测试:用于指定轴内部的部分结点

限定谓语:0个,一个或者一个以上的判断语句:使用专用的表达式对轴和结点测试相匹配的结点做进一步限定

1.轴 ——一种相互关系,用于定位步长本身与上下文结点之间的关系

(1)self轴

返回上下文结点本身,所以说self轴返回的结电集只有自身结点一个

!!!注意:只有self::nodename才会返回结点,否则该轴的返回的值为空

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BLmXeitt-1631502088727)(file:///C:\Users\Administrator\Documents\Tencent Files\3022614399\Image\C2C\8D48954A598FACE6C47ABD68D0F596E7.jpg)]

(2)child轴

child轴是一个最常用的轴,表示上下文结点的子结点 。child轴是默认轴。也是一个向前轴,向前轴是文档顺序的通常方向

(3) parent轴

表示上下文结点的父结点。对于任意给定的结点,只可能有一个父结点。也是一个逆向图,表示了与正常文档的顺序相反的方向

(4)descendant轴

(5)descendant-or-self轴

(6)ancestor轴

(7)ancestor-or-self轴

(8)following轴

(9)following-sibling轴

(10)preceding轴

(11)preceding-sibling轴

(12)attribute轴

(13)namespace轴

2.结点测试

几种XPath的常见语法:

(1)nodename 从指定轴匹配的所有结点集中选出名称为nodename的结点

(2)node( ) 选择与指定轴匹配的所有类型的结点

(3) text( ) 选择与指定轴匹配的所有文本类型的结点

(4)comment( ) 选择与指定轴匹配的所有注释结点

(5)processing-instruction( ) 选择与指定轴匹配的所有处理指令结点

(6)* 是结点测试的通配符,不对指定轴进行任何过滤获取所有元素结点以及文本结点

书上代码 例7-4 7-5

(1)Nodename:<xsl:value-of select =“child::node( )”/> 的XPath路径child::root是一个相对路径,表示筛选根结点上名为root的结点,得到的结点集结果为

<id>100</id><id>101</id><id>102</id><name>Dora</name><xsl:value-of>标记将结点集中的文本内容显示出来:    root content 100 101 102 Dora

(2)node( ):<xs:value - of seclect =“child::node( )”/>的XPath路径child::node( )是一个相对路径,表示根结点子轴的所有结点,根结点的子轴的所有结点,根结点的子轴即为整个文档(除了属性之外)筛选之后的结点集结果如下:

<? style-sheet type="text/xsl" href="nodetestdemo.xslt"?><root>root content    <id>100</id>     <id>101</id>     <id>102</id><name>Dora</name></root><xsl:vaalue-of>   标记将结点集中的文本内容显示出来    type ="tye/xsl" href="nodetestdemo.xslt" demo comment root content 100 101  102 Dora

(3)text( ):<xs:value - of seclect =“child::node( )”/>的XPath路径child::node( )是一个相对路径,表示将当前结点(根结点)子轴上名为root的结点筛选出来

筛选结果如下:

root content <xsl:value-of >标记将结点集的文本内容显示出来root content 

(4) processing-insruction:

<xsl:value-of delect=“child:: processing-instuction ( )”/?>的XPath路径child::processing-instruction ( ) 一个相对路径,表示出筛选当前结点子轴的处理指令的结点集

(5)comment( )

<xsl:value-of delect=“child::comment ( )”/?>的XPath路径child::comment( ) 一个相对路径,表示出当前结点子轴下的注释结点集

(6)* <xsl:value-of delect=“child:: ( )”/?>的XPath路径child:: ( ) 一个相对路径

*表示不对获取的元素结点集进行过滤,筛选出结果如下。

(7)element (nodename,type):

共两步,第一步获取子轴上名为root的结点集,第二步在获取结点集的基础上,获取子轴上的元素,

element(*,string)对元素进行筛选,只保留Schema中定义为xs:string类型的元素

(8) attribute(nodename,type):

共分三步:

第一步获取子轴上名为root的结点集,第二步在获取结点集的基础上,获取子轴中的第一个名为id的元素,,第三步获取attribute轴上的属性,并且通过attribute(*,xs:string)筛选得到所有类型为xs:string的属性结点

3.谓词

<!--谓词的含义是筛选所有文本内容等于100的结点集-->一个谓词<xsl:value-of select="child::root/child::*[text()=100]">    </xsl:value-of>                               <!--谓词的含义是筛选所有文本内容等于100或者等于102的结点集-->    多个谓词<xsl: value-of select="child::root/child::*[text()=100 or text()=102]">    </xsl:value-of>

分析上述代码:

(1)<xsl:value-of select=“child::root/child:: *[text()=100]”>
< /xsl:value-of>

其中 < /xsl:value-of>标记将所有结点集的文本内容显示出来,此处显示结果为100

简化路径

child::————省略

attribute::————@

self::————.

parent::————…

descendant-or-self::——//

[position( )=1]——[1]

应用到实例中

(1)child::root 对等简化路径为root 表示从当前结点集中获取子轴结点集中名为root的所有结点

(2)self::node( )/root 简化路径为./root 表示从当前结点集中获取self轴结点集,再从子轴的结点集中筛选出中名为root的所有结点

(3)root/parent::node( ) 简化路径为root/… 表示从当前结点集中获取子轴的结点集,再从parent轴中获取所有结点

(4)descendant-or-self::id 简化路径为//id ,表示从当前结点集中获取子轴及其后代轴中名为id结点集

(5)//id[position( )=1] 简化路径为//id[1] 表示从当前结点集中获取子轴及其后代中名为id的结点集,通过谓词最后筛选出结点集中最后第一个结点

7.4 XPath运算符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qe2BRIva-1631502088728)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210606145234001.png)]

XPath表达式的计算结果有四种:

(1)结点集:一个排序的没有重复的结点集合

(2)布尔值:可以是true和false

(3)数字:一个浮点数值

(4)字符串:字符串数据

7.5 XPath函数

调用XPath的函数格式如下:

functionname([arg]*)functionname:是被调用的函数名称arg:函数的变量,如果有多个,用,隔开

1.结点集函数库

last(): 返回当前选中结点集的最后一个结点的位置,是一个数字。position():返回当前正在处理的结点处于选中的结点集的位置,是一个数字。count(ns):返回当前选中的结点集的结点数量。local-name(ns?):返回传入结点的本地部分。namespace-uri(ns?):返回传入节点的命名空间部分URI部分。name(ns?):返回传入节点的完整扩展名称,如果有命名空间则包括命名空间URI部分。

2.布尔函数库

boolean(obj):用于测试参数“obj”是否存在。如果obj指定的是一个结点集,当且仅当指定结点集不为空时返回的结果才是真。如果是一个字符串,当且仅当字符串长度大于零时返回值才是真。如果是一个数字,当且仅当数字大于零才返回真。否则返回的结果为假。not(boolean):对参数取反,即传入真时返回假,当传入假时函数返回值为真。true():简单地返回true 。false():简单地返回false 。lang(str):返回值为布尔值,根据上下文结点是否有xml:lang属性,且它的值是否等于”str”指定的。如果有且相等,则返回true。

3.数字函数库

number(obj):将一个对象转换为数字。sum(ns?):把传入的节点集中每一个结点转换为数字并求和。floor(num):利用截断的原则取整的函数。ceiling(num):利用进一法的原则取整的函数。round(num):返回四舍五入的原则取整的函数。

4.字符串函数库

string(any):以XPath中的四种类型对象为参数,并将其转换为一个字符串。concat(string,string,...):传入参数为字符串或模式表达式,返回由两个或更多字符串组成的字符串。substring(string,number,number?):返回指定位置的子串contains():检查字符串中是否包含另外一个字符串。

7.6表达式

7.7 本章小结

第八章:XSLT

8.1 XSLT概述

8.2 在XML中引用XSLT

8.3 XSLT的转换模式

8.4 XSLT的基本语法

模板以及模板调用

1.模板规则

原XML文档

<?xml version="1.0" encoding="UTF-8"?><students><student id="20100101"><name>王宏</name><java>96</java><oracle>88</oracle><uml>90</uml></student><student id="20100102"><name>李娜</name><java>76</java><oracle>56</oracle><uml>70</uml></student><student id="20100103"><name>孙武</name><java>77</java><oracle>70</oracle><uml>80</uml></student></students>

代码8-11

<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XSL/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" >	<xsl:output method="html"  encoding="gb2312"></xsl:output>	<!--模板规则,当前定义的模板为根模板,XSLT解析器从根模板开始执行-->	<xsl:template match="/">	<html>		<head>			<title>成绩单</title>		</head>		<body>		<table border="1">			<tbody>				<tr>					<th>姓名</th>					<th>java成绩</th>					<th>Oracle成绩</th>					<th>UML成绩</th>				</tr>				<!--调用模板规则,调用匹配students标记的模板规则-->				<xsl:apply-templates select="students"/>			</tbody>		</table>		</body>	</html>	</xsl:template>	<!--模板规则 当前定义的模板匹配student标记-->	<xsl:template match="students">	<tr>	<!--显示select属性值XPath的指定的结点集内容-->	<td><xsl:value-of select="student[1]/name"/></td>	<td><xsl:value-of select="student[1]/java"/></td>	<td><xsl:value-of select="student[1]/oracle"/></td>	<td><xsl:value-of select="student[1]/uml"/></td>	</tr>	</xsl:template>	</xsl:stylesheet>

生成结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t7Uqm1u5-1631502088729)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210621174448633.png)]

代码8-13使用mode属性的XSLT文件代码

<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XSL/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" >	<xsl:output method="html"  encoding="gb2312"></xsl:output>	<!--模板规则,当前定义的模板为根模板,XSLT解析器从根模板开始执行-->	<xsl:template match="/">	<html>		<head>			<title>成绩单</title>		</head>		<body>		<table border="1">		<tbody>			<tr>				<th>姓名</th>					<th>java成绩</th>					<th>Oracle成绩</th>					<th>UML成绩</th>		</tr>		<!--调用模板规则,调用匹配students且mode属性值为a的模板规则-->		<xsl:apply-templates select="students" mode="a"/>		</tbody>		</table>		<hr/>		<!--调用模板规则,调用匹配students且mode属性值为b的模板规则-->		<xsl:apply-templates select="students" mode="b"/>		</body>		</html>	</xsl:template>	<!--模板规则 当前定义的模板匹配students,由于匹配students的模板规则不止一个,因此使用mode属性,属性值保证唯一命名为a-->	<!--当前模板规则用于显示学生成绩的表格--><xsl:template match="students" mode="a"><tr><!--显示select属性值XPahth指定的结点集内容-->	<td><xsl:value-of select="studnet[1]/name"/></td><td><xsl:value-of select="studnet[1]/java"/></td><td><xsl:value-of select="studnet[1]/oracle"/></td><td><xsl:value-of select="studnet[1]/uml"/></td></tr><tr><!--显示select属性值XPahth指定的结点集内容-->	<td><xsl:value-of select="studnet[2]/name"/></td><td><xsl:value-of select="studnet[2]/java"/></td><td><xsl:value-of select="studnet[2]/oracle"/></td><td><xsl:value-of select="studnet[2]/uml"/></td></tr><tr><!--显示select属性值XPahth指定的结点集内容-->	<td><xsl:value-of select="studnet[3]/name"/></td><td><xsl:value-of select="studnet[3]/java"/></td><td><xsl:value-of select="studnet[3]/oracle"/></td><td><xsl:value-of select="studnet[3]/uml"/></td></tr></xsl:template>	<!--模板规则,当前定义的模板匹配students,由于匹配students的模板规则不止一个,因此要使用mode属性,属性值保证唯一命名为b--><!--当前模板规则用于平均成绩的无序列表表示--><xsl:template match="students" mode="b"><ul>	<li>java平均成绩:<xsl:value-of select="avg(//java)"/></li>	<li>java平均成绩:<xsl:value-of select="avg(//oracle)"/></li>	<li>java平均成绩:<xsl:value-of select="avg(//uml)"/></li>	</ul></xsl:template>	</xsl:stylesheet>

8.5 XSLT的复用

8.6 XSLT进阶

第九章:XQuery基础

第十章:XQuery应用

第十一章:DOM

11.1 XML文档解析技术

XML文档本身是以纯文本对数据进行编码的一种格式。

常用的XML文档的解析技术

1.DOM

文档对象模型,可用于直接访问XML文档的各个部分,在DOM中,文档被模拟为树状,其中XML语法的每个组成部分都被表示为一个节点

2.SAX

XML的简单应用程序接口 基于事件的API,不需要调用解析器而是解析器调用程序,不要求将整个XML文件一起装入内存

3.JDOM

JAVA文档对象模型,给JAVA程序员提供一套简单易用的操作XML的API

4.DOM4J

5.Digester

SAX和DOM比较

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uXHllvRp-1631502088729)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210610165516758.png)]

SAX适用于处理下面的问题:
对大型文件进行处理;
只需要文件中的部分内容,或者只需要从文件中获取特定的信息;
需要建立自己的对象模型。

DOM适用于解决的问题类型:
需要对文件进行修改;
需要随机对文件进行存取

JAXP

11.2 使用DOM解析XML文档

DocumentBuilderFactory dbf=DocumentBuilderFactory.nerInstance( );try{DocumentBuilder db=dbf.newDocumentBuilder( ); Document doc=db.parse(new File("被解析的ML文件的名称"));}catch (ParserConfigurationException e) {    e.printStackTrace( );}

1.DocumentBuilderFactory的对象通过DocumentBuilderFactory类调用静态方法newInsance方法得到,获取DocumentBuilder对象的工厂类实例

2.DocumentBuilder接口的对象需通过获取的DocumentBuilderFactory实例调用newDocumentBuilder方法得到,DOM解析器被称为DocumentBuilder

3,通过获取的DocumentBuilder实例调用DocumentBuilder接口的parse方法来解析XML文档

被解析的XML文档被封装为File对象,作为Parse方法的参数传入

被DOM解析的XML文档,在内存中为一个Document对象。Document对象代表了整个XML文档,包含一个或者多个Node,并排成一个树形结构。如果需要对XML文档进行访问或者操作,只需要操作Document对象,然后进行相关处理即可。

DocumentBuilderFactory类除了可以获取解析器对象外,还可以通过一些方法的设置来控制解析器的行为(见书上270页表11-2)

DocumentBuilder类中定义了5种用于解析XML文档的的Parse方法

(1)Document parse(File f):解析File对象中封装的XML文档,上述代码使用的这种方法

(2)Document parse(InputSource is ):解析InputSource输入源中的XML文档,在利用当前parse方法解析时,代码

db.parse(new InputSource("demosax01.xml"));

(3)Document parse(String uri):解析系统URI所代表的的XML文档,在利用parse方法解析时,代码

db.parse("demosax01.xml");

(4)Docum parse(InputStream is):解析InputStream 对象源中的XML文档,在利用parse方法解析时,代码

db.parse(new InputStream("demosax01.xml"));

(5)Document parse(InputStream is,String systemId):给定的InputStream内容解析为一个XML文档,systemId是一个与解析相关的URI基础

解析完的XML文档,在内存中被保存在Document对象中,如果需要继续对XML文档进行解析,则需要操作Document对象,Document对象中的方法包括很多访问XML文档的方法,以及修改输出XML文档

11.3 DOM接口及其应用

DOM在分析XML文档时把所有的内容映射成结点,所有的结点形成一个树形结构,我们通过访问这个结点树来访问

XML文档,Node代表了Dom模型的一个树形结构,没有具体的结点类型。

1.Element

2.Attr

3.Text

4.CDATASection

5.NodeList

6.NameNodeMap

7.Commet

8.ProcessingInstruction

9.DocumentFragment

10.实体,实体引用和记号结点

第十二章:SAX

12.1 SAX概述

12.2 使用SAX解析XML文档

12.3 SAX接口及其应用

12.4 DefaultHandler和DefaultHandler2类开发实践

第十三章:JDOM和DOM4J

  • 3
    点赞
  • 2
    评论
  • 2
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

评论 2 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页

打赏作者

D-esolate

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值