一) XML优点
先让我们了解一下什么是XML(扩展标识语言). XML属于SGML(Standard Greneralized Markup Language 标准通用标记语言)的一个子集, 它是一种采用标记来描述文档(数据)的种类和方法. XML是由W3C下属的XML小组在JonBosak 的领导下于1996年完成的规范, 1998年正是成为一种W3C推荐的标准. 使用过HTML的开发人员都知道, HTML是属于树状结构, 并且使用<…> 和 <…./>作为节点的起始和结束标识. XML的结构也是类似. 但它却比HTML有更多的灵活性, 你可以自己定义自己的节点名称和内容.
使用XML的主要优点是:
1. 它是基于文本的, 可以广泛的在局域网/互联网上传输
2. 能被各种平台上的应用程序(脚本)所理解, 前提是开发者知道这个文档的机构
3. 可以描述各种信息, 比如 客户/服务器的状态, 数据记录集合, 程序控制/配置信息. 理论上XML可以描述任何东西, 不夸张的说, 甚至可以让一台计算机上程序通过XML转移到另外一个计算机上执行, 但输出结果又可以在另外一个计算机上显示.
4. 良好的可读性, 这不仅使程序能理解XML所描述的信息, 也易于开发人员理解其意义.
我个人认为最突出的优点应该属第3点, 第一次让我感到惊讶的是在微软的模拟飞行游戏中, 其中的配置文件居然全部是使用的XML. 由于它的这一优点, 使得它在B/S系统中广泛运用, 典型的一个就是用于描述从服务器上返回的数据集.
下面我们再来看看另外和XML相关的几个名词, 有兴趣的朋友可以了解一下:
DTD(Document Type Definitions) 文档类型定义, 用于描述XML的约束条件, 即描述那些信息可用, 这也信息又是什么意思.其可以使用 XML模式(XML Schema 我更喜欢叫它为XML 架构)来代替, 比如 用Delphi的TQuery.SaveToFile 时保存的XML文档就是用的XML模式. 有兴趣的朋友可以看看Delphi导出的XML数据结构.
XSL(Extensible Stylesheet Language) 扩展的样式语言, 用于描述XML文档如何再图形媒介上显示. 常去CSDN的开发者应该都知道, 它就使用的这个来格式化XML在浏览器页面的输出.
二) XML的结构
上面提到XML为一个树形结构, 所以其必须要有一个唯一的根节点, 就像HTML中的<html>…</html>标识一样. 下面我们通过一个小的XML来描述XML常用到的结构.
1<?xml version="1.0" encoding="gb2312"?> <!--文档版本信息, 注释格式同HTML-->
2<XMLPackage>
3 <clinetinfo ip=”10.28.65.21” handler=”si” unit=”安徽马鞍山社会养老保险处”/>
4 <data>
5 <row id=”1” name="子蓝" sex=”男” age="24" duty="软件工程师"/>
6 <row id=”2” name="天使蓝" sex=”女” age="25" duty="商务经理"/>
7<!--data中包含了元素 row的两个实例,通过属性id予以区分 -->
8 </data>
9 <memo length=”16” color=” $0034494B”>Hello! I am nth! </memo> <!-- 这个元素中间包含的内容成为Text,而且也含有两个属性 length, color, 当然也可以没有属性 -- >
10 <Actions acition=”update/insert”/> <!—该元素描述了一动作控制信息-->
11</XMLPackage>
(注意: 前面的数值标号, 只是我这里方便讲解自己加的, 正规的文档是没有的.)
好, 看了上面的格式是不是觉得有点眼熟了, 我想你现在应该基本上能看懂它描述的意义了. 很简单吧,对,就是这么简单。下面以此为例了解一下这个文档的意义和格式要求.
第1行为XML 头说明, version 标识这个文档格式的版本号, encoding 标识文档使用的语系. 为什么要使用verision 呢? 这是因为在分布的应用系统中, 可能存在版本升级的问题. 比如现在新出了一个2.0的版本, 服务器已经更新为2.0的版本了, 但客户端还使用的是原原来1.0的版本, 这样通过这个版本号服务器端就能方便的识别哪些是可以接受的版本,哪些是该拒绝的版本.
第2行到第12行描述的是name为XMLPackage的根节点, 根节点只允许有一个. 注意节点结束时使用</…>标识的.
一个节点又叫做一个元素,由< nodename > text </ nodename >或者< nodename… />来封装. 前者一般用来封装比较大的文本对象(如一个文本文件或者图像),当然在<nodename 和 >之间也可以包含有属性(如9行,注意属性不能包含在元素结束位置</nodename>中) ; 后者则主要通过属性来描述对象, 如用来描述一条记录或者状态信息(比如2, 5, 6, 10行)。元素的属性之间使用空格分割。
节点(元素)是可以嵌套使用的,但不能交叉嵌套,这和For语句的嵌套规则是类似的,就不用多说了。
每个节点(属性)之间可以包含任意的空格,tab,回车和换行符号,这些都会被XML解析器自动忽略。但要注意< nodename > text </ nodename >格式的节点内部(就是text部分)包含的空格和回车符号会被XML解析器作为该节点的Textdelphi app读出。所以一般我们会采用如第9行一样的格式,而不会像下面一样书写这样的节点:
<memo length=”16” color=” $0034494B”> <!-- 这样书写会在正文前加入回车换行符号,这些符号会被XML解析器认为是正文被读入-->
Hello,girl! I am nth!
</memo>
有朋友可能就会开始问了, 那像我的图片等Bin 数据如何封装呢?
我的做法是使用MIME格式把bin数据转换为字符数据, 然后封装到XML文档中. 常用的编码为 BASE64, 当然你也可以用其他的编码格式, 比如16进制, 原则是要把Bin数据变成字符数据封装.像上面的这个文档也可以加入DTD文档或者XML模式元素, 来描述每个Row中每个属性的意义和约束.
三) 使用Delphi解析XML 文档
对于XML的解析主要有 即DOM(文档对象模型) 和SAX(Simple API for XML)。DOM是通过构建内存对象来完成XML的解析, 后者则是将解析过程转换为事件驱动。
Delphi提供了三种DOM解析程序:MSXML, Open XML,Xerces XML。MSXML是微软提供的解析程序,被实现为一系列的COM对象, 主要包括 msxml3.dll, msxml3a.dll, msxml3r.dll 三个动态链接库。
这里我只说一下通过IXMLDocument来完成XML的解析, 这里你只需要关心节点Node和节点集合NodeList 接口(Interface)既完成XML对象的获取 ,这也是我们通常会使用的方法。
首先我们来看一种通过遍历节点的方法,先来熟悉几个属性:
Version :WideString //文档的版本号。
DocumentElement :IXMLNode //根节点,比如上面实例的<XMLPackage>对象。通过根节点您就能开始遍历整个XML节点数.
ChildNodes :IXMLNodeList //当前节点的子节点集合。
Node[ Nodeindex or NodeName ] :IXMLNode // XML的节点。 通过节点,您可以通过
它的Text ,attribute 属性来获取节点的内容和属性。也可以使用GetNode、Get方法来获取节点。
对,没错,就是这么几个关键的属性就可以完成XML的解析工作。通过下面的示范程序您可以了解如何通过这几个属性来从XML中获取我们想要的信息。
Var XMLDocument :IXMLDocument;
XMLNode :IXMLNode;
begin
XMLDocument := TXMLDocument.Create( ‘d:\l’ );
XMLDocument.Active := True;
XMLNode := XMLDocumen.Document.Element;
Memo1.Line.Add( ‘根节点的名字为:’ + XMLNode.Name );
Memo1.Line.Add( ‘根节点下的子节点数目为: ‘ + IntToStr( XMLNode.ChildNodes.Count ));
XMLNode := XMLNode.ChildNodes.Node[2]; // 将当前访问的节点的第三个子节点置为要访问的节点memo.
Memo1.Line.Add( ‘根节点下的第三个子节点的名字’ + XMLNode.Name );
If XMLNode.HasAttribute( ‘color’ ) then
Memo1.Line.Add( ‘该节点的属性color:’ + XMLNode.Attribute[‘color’] )
Else
Memo1.Line.Add( ‘该节点没有属性 color, 或者大小写不正确!’ );
If XMLNode.IsTextElement then
Memo1.Line.Add( ‘该节点包含有内容Text: ‘ + XMLNode.Text )
Else
Memo1.Line.Add(‘该节点为非叶子节点, 不能包含内容Text!’ );
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论