强大的XML

2018-04-23 20:29:26

XML:Extensible Markup Language,也就是可扩展标记语言。XML和HTML格式是古老的标记通用语言SGML的衍生语言。

XML文件是可以用来作为配置文件的,相比于其他配置文件的规范,XML的好处在于通过自定义的标记,程序可以利用标记寻找相应的配置信息,这样就可以随意调整配置信息的位置,标记也能帮助用户理解配置信息的含义。

我们常常会遇到不同的商业伙伴之间会有密切的商务往来,彼此之间的信息系统需要对接,但是有可能双方使用的是不同的数据库产品,虽然这些数据库都支持SQL92标准,但是经过演变,各种各样的数据库或多或少的发展了自己的方言,这样在不同的数据库之金啊交换数据,变成了令人头疼的问题。比如,中国移动使用的是Oracle的工具,而银行使用的是DB2,那么这两者的数据交互就会称为令人头疼的问题。另外,在企业间合并的时候,多种不同的数据库之间的合并也会成为麻烦。现在有了XML,一切都变得很容易,因为XML被广泛的支持,所以XML成为了不同数据库之间数据迁移的工具。

除了在数据库领域XML利用自身标准帮助迁移数据,在非数据库领域,XML也能用来协调不同计算机语言,不同服务器平台等这些场合的数据融合。

尽管XML和HTML同宗同源,但是两者之间存在着重要的区别:

  • 与HTML不同,XML是大小写敏感的,例如<H1>和<h1>是不同的XML标签。
  • 在HTML中,如果从上下文可以分清哪里是段落或者列表项的结尾,那么结尾标签如</p>可以省略,而XML中结束标签绝对不能省略。
  • 在XML中,只有单个标签而没有相对应的结束标签的元素必须以/结尾。这样解析器就不需要查找形如</p>的标签了。
  • 在XML中,属性值必须用引号括起来。在HTML中,引号是可有可无的。例如,<applet code = "CodeDemo.class" width = 300>,这在HTML中是合法的,但是在XML中则是不被允许的,需要加上引号进行约束。所以在XML中应该写成<applet code = "CodeDemo.class" width = “300”>
  • 在HTML中,属性名可以没有值。例如,<input type = "radio" cheacked>。在XML中所有的属性都必须要有属性值。比如,<input type = "radio" cheacked=“true”>

一、XML文档的结构

1、XML应该以一个文档头开始,例如:<?xml version="1.0" encoding="UTF-8"?>。encoding不是必须的,?与xml之间不能有空格,XML语法规定是相当严格的。

2、文档头之后通常是文档的文档类型定义(Document Type Definition,DTD)。

3、XML的标记以<>为开头,以</>为结尾,完整的这样一个结构被称为元素,和html不同的是,html里的元素都是事先规定好的,而XML的标记是作者自己规定的。

XML文档的正文包含根元素,根元素包含一些其他的元素。元素可以有子元素(child element),文本或者两者皆有。在下述的例子中,font元素有两个子元素,它们是name和size。

<?xml version="1.0"?> --文档头<!DOCTYPE configuration ...>  --文档的类型定义DTD
<configuration><title><font><name>Java</name><size>36</size></font></title>
...
</configuration>    

4、XML其他的一些指令

  • 字符引用

字符引用的形式是&#十进制值,或者&#x十六进制值。例如,字符a,&#97,或者&#x61。

  • 实体引用

实体引用的形式是&name,例如&lt;&gt;&amp;&quot;&apos,都有预订的含义:小于,大于,&,引号,省略号。

  • CDATA部分

CDATA部分用<![CDATA[...]]>来限定其界限。它们是字符数据的一种特殊形式。你可以用来囊括那些含有<,>,&之类的字符的字符串,而不用将它们解释为标记,例如:

<![CDATA[<&>是很常用的]]>。但是这里的字符串是不能包含]]>的,这也可以理解。

  • 处理指令

处理指令是那么专门用来处理XML文档的应用程序中使用的指令,它们将用<? 和 ?>来限定其界限。例如:

<?xml version="1.0"?>

  • 注释

注释是用<!--  -->限定的文本,例如:

<!-- This is a comment -->

另外,注释中是不能包含--的。注释只能用来给读者提供信息,其中绝对不能包含隐藏的命令,命令应该是用处理指令来实现的。

 

二、文档类型定义 DTD

前面提到XML的标记不是语言事先规定的,作者可以自己来定义标记,但是这样也出现了问题,就是别人如何理解自定义的标记,更主要的是在别人修改的时候,如何遵守原始作者的定义。

从另一个角度来看,我们将XML看作一种轻量级的数据库使用,数据库操作事实上存在两个阶段,数据定义阶段和数据操作阶段,在数据操作前,通常要定义表的结构,以便数据可以按照设定有条不紊的存放。

那么,DTD就是数据类型定义(Document Type Definition)文件,DTD文件用于说明特定XML文件的规则。DTD并不是强类型定义语言,在DTD中只有两个数据类型#PCDATA和EMPTY,有数据和没有数据,对于XML的主要应用方向之一的配置文件,这样设计DTD无可厚非,因为配置文件对数据类型并没有太多的要求。

然而,在某些情况下,当我们需要更精确的数据类型定义的时候,DTD就显得束手无策了,比如我们定义的元素性别,我们希望其数据类型为男/女,这个时候DTD就无法实现,只能简单的设置成#PCDATA。

<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT 学校 (学生+)>
<!ELEMENT 学生 (姓名,性别)>
<!ELEMENT 姓名 (#PCDATA)>
<!ELEMENT 性别 (#PCDATA)>

在XML文件中使用<!DOCTYPE>来将XML文件和DTD文件进行绑定,只能是大写字母,后面是根元素标记名字。SYSTEM表示DTD在文件系统中,如果是PUBLIC则表示将使用互联网上的DTD,此时除了地址还需要额外指定DTD的名字。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE 学校 SYSTEM "‪C:\school.dtd">
<学校><学生><姓名>张三</姓名><性别>男</性别>
</学校>

 

三、Schema

Schema是DTD的替代品,它的作用也是来约束XML文件的,XML Schema 语言也称作 XML Schema 定义(XML Schema Definition,XSD)。

那么既然有了DTD为什么还需要Schema呢,我们认为 XML Schema 很快会在大部分网络应用程序中取代 DTD。理由如下:

  1. XML Schema 可针对未来的需求进行扩展
  2. XML Schema 更完善,功能更强大
  3. XML Schema 基于 XML 编写
  4. XML Schema 支持数据类型
  5. XML Schema 支持命名空间

Schema本身也是基于XML编写的,可使用 XML 编辑器来编辑 Schema 文件,使用 XML 解析器来解析 Schema 文件,并且通过 XML DOM 来处理 Schema。

一个简单的 XML 文档:

请看这个名为 "note.xml" 的 XML 文档:

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

XML Schema

下面这个例子是一个名为 "note.xsd" 的 XML Schema 文件,它定义了上面那个 XML 文档( "note.xml" )的元素:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com"
xmlns="http://www.w3schools.com"
elementFormDefault="qualified"><xs:element name="note"><xs:complexType><xs:sequence><xs:element name="to" type="xs:string"/><xs:element name="from" type="xs:string"/><xs:element name="heading" type="xs:string"/><xs:element name="body" type="xs:string"/></xs:sequence></xs:complexType>
</xs:element></xs:schema> 

首先,需要注意的是Schema也是个XML文件,所以它也有自己的命名空间。

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

其中,下面这句表示给这个XML中Schema定义了一个命名空间http://www.w3.org/2001/XMLSchema,xs为使用时的前缀。

xmlns:xs="http://www.w3.org/2001/XMLSchema"

显示被此 Schema 定义的元素 (note, to, from, heading, body) 来自命名空间: "http://www.w3school.com.cn"即这个schema是为”http://www.w3school.com.cn“命名空间所提供约束的,也就是被声明为http://www.w3school.com.cn命名空间的xml文件所引用。

targetNamespace="http://www.w3school.com.cn" 

下面是用来指出 Schema 中元素的默认的命名空间是 "http://www.w3school.com.cn"

xmlns="http://www.w3school.com.cn" 

 

四、命名空间

有时在一个团队中,不同任务的人都需要使用XML,各自设计约束难免会有元素重复的问题,使用命名空间就是用来解决这个问题的。

XML 命名空间属性被放置于元素的开始标签之中,并使用以下的语法,用于标示命名空间的地址不会被解析器用于查找信息。其惟一的作用是赋予命名空间一个惟一的名称。一个元素可以有多个命名空间,里面带前缀的是特地的命名空间,不带前缀的是默认命名空间。

xmlns:namespace-prefix="namespaceURI"

当命名空间被定义在元素的开始标签中时,所有带有相同前缀的子元素都会与同一个命名空间相关联。

很多公司使用URL作为命名空间名称,这是因为这里的URL肯定是唯一的,其实这个道理和Java包名的命名为反向域名是同一个道理。

XML 中对 Schema 的引用

此文件包含对 XML Schema 的引用:

<?xml version="1.0"?>
<note
xmlns="http://www.w3school.com.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3school.com.cn note.xsd"><to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>

在根元素中指定了默认命名空间为http://www.w3school.com.cn

xmlns="http://www.w3school.com.cn" 

又定义了一个命名空间xsi(官方叫XML Schema 实例命名空间)。定义这个命名空间的原因是,schemaLocation 属性在这个命名空间下,也就是说,只有先定义了这个命名空间,才能使用schemaLocation 属性。上文已经提到了,命名空间的URI是只是作为区分字符串使用的,并不包含真正的XSD文件,真正的XSD文件的位置需要通过xsi下的schemaLocation属性进行定义。

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

设置xsi前缀代表的命名空间中的一个属性schemaLocation为"http://www.w3school.com.cn note.xsd"。

XML Schema 实例命名空间下的schemaLocation属性,实际语法其实是, xsi:schemaLocation = "key" "value"。

也就是说 xsi 命名空间下 schemaLocation 元素的值为一个由空格分开的键值对。前一个“键” http://www.w3school.com.cn 指代 namespace, 只是一个全局唯一字符串而已。后一个值指代 【XSD location URI】 , 这个值指示了前一个命名空间所对应的 XSD 文件的位置, xml parser 可以利用这个信息获取到 XSD 文件, 从而通过 XSD 文件对所有属于命名空间  http://www.w3school.com.cn 的元素结构进行校验, 因此这个值必然是可以访问的, 且访问到的内容是一个 XSD 文件的内容。

xsi:schemaLocation="http://www.w3school.com.cn note.xsd"

 

五、XML文件设计

  • 在设计XML的时候,应该尽量使元素要么包含子元素,要么包含文本。换句话说,你应该避免以下的情况:
<font>Java<size>36</size>
</font>

在XML规范里,这叫做混合式内容(mixed content)。如果包含混合式的内容那么在树形遍历子节点的时候就会出现需要进行判别的情况。所以要避免混合式内容,这样可以简化解析的过程。

  • 何时使用元素,何时使用属性

这个问题在XML设计人员中存在着分歧。例如将font做如下的描述:

<font name="Java" size="36"/>

似乎要比下面的更简单一些:

    <font><name>Java</name><size>36</size></font>

但是属性的灵活性要差很多,假设你想把单位添加到size中去。如果使用属性,那么必须把单位添加到属性值中去:

<font name="Java" size="36 pt">

o no!这时候就需要对字符串“36 pt”进行解析,而这正是XML设计用来避免的麻烦。但是,如果把属性加到size元素中就会非常的方便:

    <font><name>Java</name><size unit="pt">36</size></font>

一个常用的经验法则是,属性值应该用来修改值的解释,而不是用来指定值。在HTML中属性的使用规范很简单:凡是不显示在网页上的都是属性。

 

六、XML解析

用程序读写XML,要说这不该是问题,因为大多数编程语言都有IO流的支持,但是深入的看就会发现,写XML用IO流相对容易,可以读取却并不那么容易,因为我们的需求往往不仅仅要有读取文件内容的能力,在大多数情况下,我们需要获取某一个特定元素的值,如果单纯依赖IO流,每次都需要写比较复杂的分析程序,而这些代码完全可以复用。

因此W3C提出了一个统一的标准DOM,文档对象模型(Document Object Model,简称DOM)。DOM的思想是将XML文件读到内存中,使其形成一个对象,这个对象内在映射着XML文件的树形结构,我们可以通过调用对象的成员方法来访问这些内容。

W3C做这件事还有一个巨大的好处,DOM不是建立在某个编程语言的基础上的,作为一个国际标准,几乎所有的编程语言都实现了这个标准,这样不同的语言利用DOM访问XML的做法就基本一致了。

XML技术的有趣之处在于总是有两个相同功能的不同技术,比如DTD和Schema、CSS和XSL,现在是DOM和SAX,DOM和SAX的功能一样,都是用来解析XML文件的,不同之处在于DOM一次性将整个XML文件读入到内存中,并且包装成对象,而SAX每次只读取一行,处理完后将这一行抛弃然后处理下一行,这样做的好处是不占用太多的内存,如果XML作为数据库应用,那么有可能内容过多,文件很大,使用DOM或许会超出内存的大小,这时就只能使用SAX,但是这样也说明SAX应用不如DOM频繁,因为读取很大的XML文件的机会并不多,SAX的另外一个缺点就是,因为数据会被丢弃,所以和DOM相比无法再次使用数据。

 

转载于:https://www.cnblogs.com/TIMHY/p/8921804.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/280447.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rest_framework03:查询所有/新增数据/删除一个数据/封装Response/序列化与反序列化

查询所有 1.创建新clase和url&#xff0c;避免与查询一个功能逻辑混乱。 2.增加manyTrue&#xff0c; book_serBookSerializer(books,manyTrue) urls.py: path(books/,views.BooksView.as_view()) views.py class BooksView(APIView):def get(self,request):response_msg …

如何对DevOps数据库进行源代码控制

提纲&#xff1a; 包括索引在内的数据库模式需要进行源代码控制诸如查询表这类用于控制业务逻辑的数据需要进行源代码控制开发人员需要一种能够便捷地创建本地数据库的方法共享数据库的更新只能通过构建服务器完成 健壮的DevOps环境需要对系统的每个组件进行持续集成。但是&…

自定义异常最佳实践_播放,自定义和组织媒体的最佳文章

自定义异常最佳实践Computers today are used for much more than generating documents, writing and receiving email, and surfing the web. We also use them to listen to music, watch movies and TV shows, and to transfer media to and from mobile devices. 如今&…

CSS中的路径裁剪样式clip-path

前面的话 CSS借鉴了SVG裁剪的概念&#xff0c;设置了clip-path样式&#xff0c;本文将详细介绍路径裁剪clip-path 概述 clip-path属性可以防止部分元素通过定义的剪切区域来显示&#xff0c;仅通过显示的特殊区域。剪切区域是被URL定义的路径代替行内或者外部svg&#xff0c;或…

socket编程学习笔记

socket编程&#xff1a; 1、网络基础知识 两台计算机通过网络进行通信&#xff0c;首先两台计算机要有唯一的标识&#xff0c;即唯一的IP地址。其次他们要有共同的语言用来交流即协议。再者&#xff0c;每套主机要有相应的端口号。  TCP/IP协议&#xff1a;   --TCP/IP协议是…

rest_framework04:ModelSerializer/Serializer高级用法

ModelSerializer 1.减小序列化类代码 2.不需要重写update&#xff0c;create ser.py class BookModelSerializer(serializers.ModelSerializer):class Meta:modelBookfields__all__ #序列化全部字段# fields(name,price) # 序列化指定字段# exclude(name,) # 与fields 不能…

配置本地及网络yum源(详细步骤)

我们以centos6为范例演示 1、[rootCentos6 ~]# cd /etc/yum.repos.d/ [rootCentos6 yum.repos.d]# ls CentOS-Base.repo CentOS-fasttrack.repo CentOS-Vault.repoCentOS-Debuginfo.repo CentOS-Media.repo先罗列出相关文件 2、[rootCentos6 yum.repos.d]# vim CentOS-Base.rep…

macos mojave_如何修复macOS Mojave上的模糊字体(使用亚像素抗锯齿)

macos mojaveApple’s macOS Mojave disables subpixel antialiasing, also known as font smoothing, by default. On a MacBook Air or a desktop Mac hooked up to a non-Retina display, upgrading will make your fonts look worse. 苹果的macOS Mojave默认情况下禁用子像…

为什么我要写博客

原因在这啦 一、我觉得分享是一种精神&#xff0c;分享是我的乐趣所在&#xff0c;不是说我觉得我讲得一定是对的&#xff0c;我讲得可能很多是不对的&#xff0c;但是我希望我讲的东西是我人生的体验和思考&#xff0c;是给很多人反思&#xff0c;也许给你一秒钟、半秒钟&…

一个变量命名神器:支持中文转变量名

变量命名的规范&#xff0c;对于我们编程&#xff0c;大家都知道是非常重要的&#xff0c;上次给大家推荐过一个命名辅助工具《程序员还在为变量取名苦恼&#xff0c;那是因为你不知道&#xff0c;这个变量命名神器》&#xff0c;但大家一致反馈存在2个问题&#xff1a;1、网速…

rest_framework05:GenericAPIView用法/扩展类5个/子类9个/ViewSetMixin 自定义方法名字

GenericAPIView 1.视图层类使用GenericAPIView继承&#xff0c;能简化类里的方法code。 2.简化后的方法code格式基本通用&#xff0c;简单修改即可应用到其他类。 一、class开始加入 queryset Book.objectsserializer_class BookModelSerializer 二、方法里获取对象 a.查…

1.操作系统概述

2019独角兽企业重金招聘Python工程师标准>>> 操作系统的发展过程 无操作系统的计算机系统单道批处理系统&#xff08;50年代&#xff0c;系统资源利用率低&#xff09;多道批处理系统&#xff08;60年代&#xff09;分时系统&#xff08;70年代&#xff09;实时系统…

测听hl和nhl的区别_播放NHL曲棍球的最便宜方法(无电缆)

测听hl和nhl的区别If you’re like me, you watch hockey, and…basically no other sports. You also, like me, would like to skip the cable subscription. So what’s the cheapest way to watch NHL hockey online so you can cut the cord? 如果您像我一样&#xff0c;…

制作一个让客户满意的软件

我看了《构建之法》的第八章“需求分析”我对如何制作一个让客户满意的软件有了一点儿头绪&#xff0c;的但是还是有一些迷惑。我通过看书总结和百度查找有了一点儿总结&#xff1a;我们在制作软件的过程中应该及时与用户沟通交流&#xff0c;交换意见&#xff0c;并及时实现用…

rest_framework06:自动生成路由\action使用\认证

自动生成路由 # 1.导入routers模块 from rest_framework import routers# 2.实例化类 routerrouters.SimpleRouter()# 3.注册 # (前缀,继承自ModelViewSet视图类,别名) router.register(books7,views.BooksView) # 不要加斜杠# 4.加入 urlpatternsrouter.urls action使用 装…

char data[0]在struct末尾的用法

在实际的编程中&#xff0c;我们经常需要使用变长数组&#xff0c;但是C语言并不支持变长的数组。此时&#xff0c;我们可以使用结构体的方法实现C语言变长数组。 struct MyData { int nLen; char data[0];}; 在结构中&#xff0c;data是一个数组名&#xff1b;但该数组没有元素…

使用Java实现K-Means聚类算法

2019独角兽企业重金招聘Python工程师标准>>> 关于K-Means介绍很多&#xff0c;还不清楚可以查一些相关资料。 个人对其实现步骤简单总结为4步: 1.选出k值,随机出k个起始质心点。 2.分别计算每个点和k个起始质点之间的距离,就近归类。 3.最终中心点集可以划分为…

在PowerShell中显示高级进度条

如果你需要编写一些PowerShell脚本&#xff0c;尤其在处理一些相对复杂的任务时&#xff0c;你可能希望添加进度条的功能&#xff0c;以便随时可以了解进展情况。Write-Progress 这个命令可以帮助你完成简单的需求&#xff0c;请参考官方文档即可&#xff0c;但下图一个示例&am…

当检测到运动时如何自动打开门灯

If it’s dark out and someone comes to your door, you probably can’t see them unless your porch light is on. Furthermore, if a potential burglar approaches your front door, a motion light can help scare them away. 如果天黑了&#xff0c;有人进了您的门&…

分布式系统的那些事儿(六) - SOA架构体系

有十来天没发文了&#xff0c;实在抱歉&#xff01;最近忙着录视频&#xff0c;同时也做了个开源的后台管理系统LeeCX&#xff0c;目前比较简单&#xff0c;但是后续会把各类技术完善。具体可以点击“原文链接”。 那么今天继续说分布式系统的那些事。 我们现在动不动就讲分布式…