漫漫技术人生路

C#

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
1、XML的合法性验证 

        应用XML技术的一个主要目标是为了方便信息交换。很显然,只有XML文档的格式或是结构得到交互各方的一致认可,这个目标才有可能实现。XML Schema(模型)和DTD就是描述信息结构的模型,可以用来对XML文档内容的合法性进行验证。  
        Schema和DTD规定了在文档中能够使用的元素和属性,以及这些对象与文本内容的可能组合形式。作为对文档验证的标准,Schema和DTD不仅应该能被人们理解,对应用程序来说也应当是易于理解的。对文档合法性的验证包括两个方面:一方面是语法结构的验证,即元素类型、元素嵌套格式、属性类型、属性值数据类型、属性值是否可选等相关文档对象单元本身及其结构的合法性;另一方面是语义的验证,只有真正理解了XML文档的含义才能算是实现了信息交互,否则仅是结构上正确但意义模糊的信息,对于接收方来说一样是无用的,有时甚至会产生误解,起到相反的作用。
对XML文档的验证有如下几个步骤:
1.定义一份XML Schema或DTD: Schema或DTD为同一类型的所有文档定义了结构标准,比如有关书籍信息的文档可共享一份标准。
2.应用Schema或DTD:一般由文档的作者指定Schema,这样接收方可以很快地根据说明对文档进行验证。但在C/S(客户机/服务器)环境中,由于服务器无法判断XML在客户端是否已经验证过,所以为了能够确保验证过程,也为了避免可能的重复验证,对文档应用Schema或DTD的操作由服务器完成。
3.运行解析器进行验证:解析器在装载文档的同时扫描结构,遇到任何错误都会终止装载过程,并做出适当的响应。

2、Schema和DTD的区别 
虽然,XML Schema和DTD都是用于文档验证,但二者还是有一定的区别,其中前者更为精确和灵活:
● XML Schema是一种内容“开放”的模型,可扩展、功能强,而DTD是内容“封闭”的模型,可扩展性差;
● XML Schema支持丰富的数据类型,完全能够满足网络应用特别是电子商务的需求,而DTD不支持元素的数据类型,对于属性的类型定义也很有限;
● XML Schema支持名称空间机制,DTD不支持;
● XML Schema可以针对不同情况分别对整个XML文档或者是文档局部进行验证,而DTD缺乏这种灵活性;
● XML Schema的语法完全遵循XML规范,可以和DOM技术结合使用,功能强大,而DTD语法自成一体,比较难以学习。
所以,Schema很有可能取代DTD成为验证XML文档合法性的新标准。
 
3、Schema的基本元素
Schema共有8种元素:<Schema>、<ElementType>、<element>、<group>、<AttributeType>、<attribute>、<datatype>和<description>。这些元素对XML中允许的语法和结构进行了定义。注意:必须在使用Schema前对这些元素进行定义。

1.<Schema>元素
Schema文件与其他的XML文档结构非常相似,根元素为<Schema>,表明文档类型:
<?xml version=“1.0”?>
<Schema name=“mySchema”
xmlns=“urn:schemas-microsoft-com:xml-data”
xmlns:dt=“urn:schemas-microsoft-com:datatypes”>
</Schema>
其中属性name指定Schema名称,xmlns指定所属名称空间。第一个xmlns指定全文的缺省名称空间,第二个定义了文档中可使用的数据类型的名称空间。
在XML中引用Schema的方法是在XML文档的根元素中使用名称空间指明Schema文件的URL地址,在URL前要加上“x-schema”前缀:
<?xml version=“1.0”?>
<myElement xmlns=“x-schema:http://mysite.com/myschema.xml”>
</myElement>
如果是在XML文档中的某一个元素中使用xmlns引用Schema,就是对文档进行局部合法性验证。
 
2.<ElementType>元素
<ElementType>元素用来声明XML文档中使用的新元素:
<ElementType 
name = “element tag name”
content = “empty”|“textOnly”|“eltOnly”|“mixed”
model = “open” | “closed” 
order = “one” | “seq” | “many”
dt:type = “XML data type” >
</ElementType>
Content属性规定声明的元素是否为空,是否包含文本或子元素,还是两者都有;order指定子元素的排列顺序; model规定了元素中是否可以包含未在Schema中定义的元素或属性; dt: type则指定了元素的数据类型。
 
3.<element>元素
<element>元素是对<ElementType>声明的元素的内容进行定义,说明在指定的元素类型中允许使用哪些子元素:
<element
type = “declared element type”
minOccurs = “0” | “1”
maxOccurs = “1” | “*” />
Type属性是必要的,同时要与〈ElementType〉中的name属性完全一致。minOccurs和maxOccurs属性分别指定了元素出现的最少和最多次数,默认值都为1。minOccurs为0说明元素是可选的,maxOccurs为*说明元素出现的次数不受限制。

4.<group>元素
<group>元素也出现在<ElementType>中,表达元素成组的概念。组里的对象可以是元素也可以是另一个子组。order属性制定组中元素的顺序:
<ElementType name=“...” >
<group minOccurs = “0” | “1”
maxOccurs = “1” | “*”
order = “one” | “seq” | “many” >
<element type=“……” />
</group>
</ElementType>

5.<AttributeType>元素
<AttributeType>元素定义了Schema中使用的属性类型。根据出现位置不同,其作用范围也不一样。如果是在<ElementType>元素中定义,那么所定义的属性类型就只能作用在该元素类型上; 如果定义在外部,那么文档中所有的元素类型就都可以使用该属性。
<AttributeType 
name = “attribute name”
dt:type = “XML data type”
required = “yes” | “no”
dt:values = “enumerated list of values”
default = “default value” > 
</AttributeType>
Name是属性类型名称; dt:type同<ElementType>元素中的用法一样 ;required指定该属性对于引用它的元素是否是必要的;dt:values只有当dt:type是“enumeration”时才有效,此时它列举属性的所有可能取值; default指定属性类型的缺省值,并且一定是有效值,比如属性类型是枚举型时,default取值一定是dt:values所列举值中的一个。
6.<attribute>元素
<attribute>元素对<AttributeType>声明的属性进行具体的定义:
<attribute
type = “declared attribute type”
required = “yes” | “no”
default = “default value” />
type属性唯一指定了引用的属性类型,取值要与<AttributeType>中的name属性完全一致; required说明该属性对于引用它的元素是否为必要的; default指定属性类型的缺省值。如果对同一属性的<AttributeType>和<attribute>中相对应的default和required属性都给出了定义,那么<attribute>的优先级别更高,以它的取值为准。
其他两个元素<datatype>和<description>分别定义了Schema元素的数据类型和为元素提供的说明资料,用法简单,本文不再一一举例说明。

1、制定Schema
考虑如下XML文档books.xml:
<?xml version=“1.0”?>
<booklist>
<book>
<title>Straight Talk About Computers </title>
<author>Lars Peterson</author>
</book>
<book>
<title>You Can Comabt Computer Stress</title>
<author>Lars Peterson</author>
<author>Carlos Diaz</author>
</book>
</booklist>
为上述XML文档制定Schema时,可以先为<title>和<author>元素制定规则,用<ElementType>定义它们为只能包含字符串的文本元素:
<ElementType name=“title” content=“textOnly” dt:type=“string” />
<ElementType name=“author” content=“textOnly” dt:type=“string” />
然后说明<book>只能包含子元素,且子元素出现的顺序是一定的。随后在内部用<element>定义<book>包括一个<title>和任意个<author>子元素:
<ElementType name=“book” content=“eltOnly” order=“seq”>
<element type=“title” />
<element type=“author” maxOccurs=“*” />
</ElementType>
最后用同样的方法说明根元素<booklist>:
<ElementType name=“booklist” content=“eltOnly”>
<element type=“book” minOccurs=“0” maxOccurs=“*” />
</ElementType>
下面的这个例子中定义了“isbn”类型的属性:数据类型是字符串,并规定如果元素中引用该属性,那么就必需赋值。
<AttributeType name=“isbn” 
dt:type=“string” 
required=“yes” />
<ElementType name=“book” 
content=“eltOnly”>
<attribute type=“isbn” />
</ElementType>

2、XML的可扩展性
由于XML Schema是一种内容开放的模型,这种可扩展性就意味着用户可以在XML Schema中使用自己定义的元素和属性。例如:
<ElementType name=“price” 
xmlns:myExt=“urn:myextensions”dt:type=“float”>
<myExt:salestax>17.5</myExt:salestax>
<myExt:bulkbuy>20</myExt:bulkbuy>
<myExt:discount>5.0</myExt:discount>
</ElementType>
其中本地的属性定义只声明了<price>元素为“float”类型,而通过名称空间又引用了其他3个标签来分别说明书籍的销售税、批量定额和折扣率。这种扩展性增强了Schema的灵活性。 
我们还可以使用DOM技术来访问扩展的Schema:
<book isbn=“9-001-122-01”>
<title>Straight Talk About Computers</title>
<price>19.99</price>
</book>
假设上述XML数据就是根据刚才的Schema定义的,而且我们已经用DOM定位了<book>元素,那么,接下来就可以访问<price>节点,并利用它的definition属性从Schema中得到<ElementType>的定义:
Set priceNode = bookNode.selectSingleNode(“price”)
Set priceElementTypeNode = priceNode.definition
salestax = priceElementTypeNode.childNodes(0).text
bulkbuy = priceElementTypeNode.childNodes(1).text
discount = priceElementTypeNode.childNodes(2).text
这样,就可以根据需要处理这些数据了。

3、在客户机/服务器环境中验证XML
在C/S(客户机/服务器)环境中,客户机和服务器都可以使用Schema来验证文档。在客户机端验证的对象可以是从服务器发来的文档,也可以是即将发送出去的文档。下面的这个例子就是用一个名为CustomerSchema.xml的Schema来验证docSubmit的xml文档,然后发送给服务器:
Set rootnode = docSubmit.documentElement
rootnode.setAttribute “xmlns”, 
“x-schema:http://server/CustomerSchema.xml”
DOM首先取得根元素的访问权,然后把xmlns设为Schema的地址,使之开始验证。
相对客户机而言,在服务器上进行验证的意义更重大,在实际中也更为常见。由于连接到服务器上的客户数非常多,所以有必要在处理它们发送来的数据前,检查收到的文档是否与预期的结构一致。验证步骤如下:
1.将XML文档载入DOM树,开始验证:
Set docReceived = CreateObject(“Microsoft.XMLDOM”)
docReceived.validateOnParse = True
docReceived.async = False
docReceived.load Request
2.判断是否链接XML Schema(只需检验一下根元素中是否设置了xmlns属性):
Set rootnode = docReceived.documentElement
If rootnode.getAttribute(“xmlns”) =
“x-schema:http://sever/CustomerSchema.xml”
Then
〈!--有,开始验证!--〉
Else
〈!--没有…… --〉
End If
3.如果没有链接,服务器就要指定一个Schema进行链接,然后将更新的文档重新装入到另一个DOM树中:
path = Server.mapPath(“CustomerSchema.xml”)
attr = “x-schema:” & path
rootnode.setAttribute “xmlns”, attr
Set docTested = CreateObject(“Microsoft.XMLDOM”)
docTested.validateOnParse = True
docTested.async = False
docTested.loadXML docReceived.xml
由于XML Schema具有许多优秀的特性,国际上许多著名公司和大企业纷纷开始向Schema倾斜,比如微软的IE 5.0就已经支持XML Schema。虽然Schema还需要在不断的实践中逐步完善,但XML Schema取代DTD已经是大势所趋,因此,笔者建议应学习并掌握这一技术。
posted on 2006-09-25 09:23  javaca88  阅读(320)  评论(0编辑  收藏  举报