具体实施方式
综述
计算机使用的数据一般以分层方式进行组织,例如符合某种模式的XML数据。即使数据在语法上符合某个模式,但是该数据在某个实质性规则集下仍然可能无效。传统上,对数据集(如消息)进行实质性验证要求设计成验证某一类消息的专用代码。本发明提供一种通用工具,它可用于验证任意类的消息,并可扩展成将任意的规则集应用于消息。本发明的机制可用于验证任何任意的数据或消息,对于这些数据或消息来说,验证参数和数据可以用XML形式表示。
示例性计算环境
图1示出了可实施本发明的诸方面的示例性计算环境。计算系统环境100仅仅是适用的计算环境的一个例子,且并不试图限制本发明的使用或功能的范围。计算环境100也不应被解释成具有与示例性操作环境100中所例示的任一组件或它们的组合相关的任何依赖性或要求。
本发明适用于许多其它的通用或专用计算系统环境或配置。可适用于连同本发明一起使用的已知的计算系统、环境和/或配置的例子包括但不限于,个人计算机、服务器计算机、手持或膝上型设备、多处理器系统、基于微处理器的系统、机顶盒、可编程消费电子产品、网络PC、小型计算机、大型计算机、嵌入式系统、包含任意上述系统或设备的分布式计算环境,等等。
可用由计算机执行的诸如程序模块之类的计算机可执行指令的一般上下文环境来描述本发明。一般地,程序模块包括例行程序、程序、对象、组件、数据结构等,它们执行特定的任务或实现特定的抽象数据类型。本发明还可在分布式计算环境中实施,在分布式计算环境中,通过经通信网络或其它数据传输媒体链接的远程处理设备来执行任务。在分布式计算环境中,程序模块和其它数据可位于包含存储设备的本地或远程计算机存储媒体中。
参考图1,用于实施本发明的示例性系统包括计算机110形式的通用计算设备。计算机110的组件可包括但不限于,处理单元120、系统存储器130以及将包含系统存储器在内的各种系统组件连接到处理单元120的系统总线121。处理单元120可代表诸如那些在多线程处理器上支持的多个逻辑处理单元。系统总线121可以是若干类型的总线结构中的任一种,包括存储器总线或存储器控制器、外围总线、以及使用各种总线体系结构中的任一种的局部总线。作为例子但非限制,这种体系结构包括工业标准结构(ISA)总线、微通道结构(MCA总线、增强型ISA(EISA)总线、视频电子标准协会(VESA)局部总线、以及外设部件互连(PCI)总线(也称为夹层(Mezzanine)总线)。系统总线121还可实现为通信设备之间的点对点连接、交换结构等。
计算机110一般包括各种计算机可读媒体。计算机可读媒体可以是计算机110可存储访问的任何媒体,包括易失性和非易失性、可移动和不可移动的媒体。作为例子,但非限制,计算机可读媒体可包括计算机存储媒体和通信媒体。计算机存储媒体包括以用于存储诸如计算机可读指令、数据结构、程序模块或其它数据之类的信息的任何方法或技术实现的易失性和非易失性、可移动和不可移动的媒体。计算机存储媒体包括,但不限于,RAM、ROM、EEPROM、闪存或其它存储器技术、CDROM、数字通用盘(DVD)或其它光盘存储、磁带盒、磁带、磁盘存储或其它磁存储设备、或能够用于存储所需信息和能够由计算机110存取访问的任何其它媒体。通信媒体一般将计算机可读指令、数据结构、程序模块或其它数据嵌入于诸如载波或其它传输机制的已调数据信号中,通信媒体包括任何信息递送媒体。术语“已调数据信号”是指信号使其一个或多个特征以编码该信号中的信息的方式被设置或改变。作为例子,但非限制,通信媒体包括诸如有线网络或直接线缆连接之类的有线媒体、诸如声音、RF、红外线或其它无线媒体之类的无线媒体。上述任何的组合也应当包含在计算机可读媒体的范围内。
系统存储器130包括诸如只读存储器(ROM)131和随机存取存储器(RAM)132之类的易失性和/或非易失性形式的计算机存储媒体。包含在诸如启动期间帮助在计算机110内的元件之间传送信息的基本例行程序的基本输入/输出系统133(BIOS)一般存储于ROM 131中。RAM 132一般包含可由处理单元120立即存取访问和/或当前正在执行的数据和/或程序模块。作为例子,但非限制,图1例示了操作系统134、应用程序135、其它程序模块136和程序数据137。
计算机110还可包括其它可移动/不可移动、易失性/非易失性计算机存储媒体。仅作为例子,图1例示了读写不可移动、非易失性磁媒体的硬盘驱动器140、读写可移动、非易失性磁盘152的磁盘驱动器151、以及读写诸如CDROM或其它光学媒体的可移动、非易失性光盘156的光盘驱动器155。可用于示例性操作环境的其它可移动/不可移动、易失性/非易失性计算机存储媒体包括,但不限于,磁带盒、闪存卡、数字通用盘、数字视频带、固态RAM、固态ROM等。硬盘驱动器141一般通过诸如接口140之类的不可移动的存储器接口而连接到系统总线121,磁盘驱动器151和光盘驱动器155一般通过诸如接口150之类的可移动的存储器接口而连接到系统总线121。
上述的和图1所例示的驱动器及其相关的计算机存储媒体为计算机110提供了计算机可读指令、数据结构、程序模块和其它数据的存储。例如,在图1中,硬盘驱动器141例示为存储操作系统144、应用程序145、其它程序模块146和程序数据147。注意到这些组件可以与操作系统134、应用程序135、其它程序模块136以及程序数据137相同或不同。这里对操作系统144、应用程序145、其它程序模块146以及程序数据147给出了不同的数字标号以说明至少它们是不同的副本。用户可通过诸如键盘162和通常称为鼠标、轨迹球或触板的指点设备161之类的输入设备,将命令和信息输入到计算机20中。其它输入设备(未示出)可包括话筒、操纵杆、游戏手柄、卫星反射器、扫描仪等。这些和其它输入设备通常通过连接到系统总线的用户输入接口160而连接到处理单元120,但也可通过诸如并行端口、游戏端口或通用串行总线(USB)之类的其它接口和总线结构来连接。监视器191和其它类型的显示设备通过诸如视频接口190之类的接口而连接到系统总线121。除了监视器之外,计算机还可包括其它外围输出设备,如扬声器197和打印机196,它们可通过输出外围接口195进行连接。
计算机110可操作于使用对诸如远程计算机180之类的一个或多个远程计算机的逻辑连接的联网环境中。远程计算机180可以是个人计算机、服务器、路由器、网络PC、对等设备或其它公共网络节点,虽然在图1中仅例示出存储设备181,但是它一般包括上述关于计算机110所描述的元件的部分或全部。图1中描绘的逻辑连接包括局域网(LAN)171和广域网(WAN)173,但还可包括其它网络。这种联网环境在办公室、企业范围计算机网络、企业内部互联网和因特网中是普遍的。
当用于LAN联网环境中时,计算机110通过网络接口或适配器170而连接到LAN 171。当用于WAN联网环境中时,计算机110一般包括用于在诸如因特网之类的WAN 173上建立通信的调制解调器172或其它手段。内置的或外置的调制解调器172可通过用户输入接口160或其它适当机制来连接到系统总线121。在联网环境中,关于计算机110所描述的程序模块或其部分可存储于远程存储设备中。作为例子,但非限制,图1例示出驻留于存储设备181上的远程应用程序185。将理解到所示出的网络连接是示例性的,可以使用在计算机之间建立通信链路的其它手段。
示例性XML数据
本发明可用于验证诸如可扩展标记语言(XML)形式的数据之类的分层组织的数据集或“消息”。XML是一种元语言,它允许根据规定的结构或模式来组织数据。图2示出了XML数据的例子,其中所描述的组织结构有助于表示邮政地址。
在XML中,数据项与元素名或“标签”(tag)名相关联。标签可用作定界符,它使用的语法约定是,定界的数据的起始处以包含在尖括号“<”和“>”中的标签名标记,定界的数据的结束处以所述标签名前加斜线并包含在尖括号内来标记。下面是遵循此约定的XML数据的一个例子:
<A>
数据由标签“A”定界
</A>
在图2中,消息200是地址。定界符<ADDRESS>(202)和</ADDRESS>(222)包围了整个消息,示出所有的数据都是“ADDRESS”元素的一部分。ADDRESS元素包括两个子元素:STREET元素和CITYSTATEZIP元素。STREET元素设置成“123主街道”(204)。CITYSTATEZIP元素是一复合元素,它包括其它元素;这些包含的元素都包围在定界符206和220之中。CITYSTATEZIP元素包括设置成“雷蒙德市”的CITY元素(208)、设置成“华盛顿州”的STATE元素(210)、以及ZIP元素,ZIP元素是一个复合元素,它所包含的元素由定界符212和218所标记。ZIP元素包括设置成“98052”的FIVEDIGIT元素(214)和设置成“0123”的PLUSFOUR元素(216)。从而,消息200按分层数据集描述了地址。
将理解到XML消息对应于树形数据结构。图3示出了对应于消息200的树300。节点302对应于图2的“ADDRESS”标签,节点302的所有子树对应于包含在<ADDRESS>和</ADDRESS>定界符202和222(示于图2)之内的元素。这些所包含的元素是STREET元素204以及CITYSTATEZIP元素。如上所述,CITYSTATEZIP元素是复合元素,它包括其它元素。节点304对应于CITYSTATEZIP标签,节点304的所有子树对应于包含在<CITYSTATEZIP>和</CITYSTATEZIP>定界符206和220(示于图2)之内的元素。这些包含的元素是CITY元素208、STATE元素210和ZIP元素。ZIP元素同样是复合元素,它包括其它元素。从而,节点306对应于ZIP标签,而节点306的所有子树对应于包含在<ZIP>和</ZIP>定界符212和218之内的元素。这些包含的元素是FIVEDIGIT元素214和PLUSFOUR元素216。可以看到,树300对应于XML消息200中的结构,并示出包含在消息200中的邮政地址的分层结构。
消息一般遵循某种类型的预定义的结构或“模式”。例如,用于“地址”消息的模式可定义可在地址中表示的各种不同类型的结构。例如,这样一种模式可将地址消息定义成包含ADDRESS标签,并可进一步定义ADDRESS标签的可允许的结构的详细内容。例如,该模式可声明ADDRESS标签包含STREET元素,以及还包含另一个元素,该另一个元素可以是CITYSTATEZIP(用于美国地址)或CITYPROVINCEPOSTCODE(用于加拿大地址),或用于美国或加拿大之外的地址的CITYCOUNTRY。对于每种类型的元素(如CITYSTATEZIP),该模式可定义该元素的构成子元素的可允许的结构。根据ADDRESS标签的这种定义,将理解到消息200及其对应的树300(如图2和3所示)仅仅是ADDRESS标签的可允许的内容的一个例子,即用于美国地址的结构,可选地是,合法的ADDRESS可包含上述的其它类型的元素之一。
实际上,该模式定义了用于XML消息的可许可的语法。然而,可能形成在某个模式下语法上正确,但违反某个本体的规则的XML消息。如下面更特别地描述地那样,本发明提供一种机制,它可用于验证XML消息的本体。
树遍历
如上连同图3所述,XML消息可看作是树。根据本发明的一个特征,较佳地以深度优先顺序来遍历由XML消息表示的树。随着遇到树中的每个节点,根据一个或多个验证表提供的信息来验证节点。下面更特别地描述了“验证”节点是什么意思以及验证表本身的结构。然而,参考图4,描述的例子示出了以深度优先顺序遍历树是什么意思。
树400包括多个节点。树400的根标记为“A”。如该图所示,根节点的孩子标记为“A1”、“A2”和“A3”。这些孩子中的每一个又依次具有孩子,标记为“A11”、“A12”、“A21”、“A22”、“A31”以及“A32”。
当以深度优先顺序遍历树400时,以某一顺序遇到树的每个节点。以深度优先顺序遍历树的算法可递归式定义。对于一给定的树:
—首先访问该树的根节点;
—然后,以从左至右、深度优先的顺序访问该跟节点的每个子树(如果有的话)
由于每个子树实际上是具有其自己的根节点的一棵树(例如A1是A的一个子树的根节点),因此,以深度优先顺序遍历子树的算法与以深度优先顺序遍历顶层树的算法相同。从而,如本领域的技术人员将理解到的那样,该遍历算法可按递归函数来实现。
从而,当使用该递归算法遍历树400时,首先遇到的节点是根节点“A”。然后以深度优先顺序遍历根节点“A”的最左边的子树。由于每个子树其本身也是棵树,因此这些子树的每一个都具有根节点。A的最左边的子树的根节点标记为“A1”。从而,在访问了节点A之后,遍历树的算法应用到以A1为根的子树,且该子树首先被访问的节点是A1。A1同样具有子树,以从左至右的顺序访问这些子树。从而,在访问A1之后,以深度优先顺序遍历以A11为根的子树。由于A11没有孩子,即A11没有子树需要被遍历,因此以深度优先顺序遍历A11右边下一个子树(即以A12为根的树)。由于A12同样没有孩子,因此无子树需要遍历。从而,完成了对A1及其子树的遍历,算法进行到遍历节点A的下一个子树(即以A2为根的子树),并且以遍历以A1为根的子树相同的方式遍历该子树。
当使用上述递归算法遍历树之后,结果是以图4所示的顺序访问了树400中的所有节点,即所述顺序是:A、A1、A11、A12、A2、A21、A22、A3、A31、A32。
示例性验证表
如上所述,XML消息可符合一模式中规定的结构或语法,并仍然可在其本体中包含无效数据。例如,如上连同图2和3所述的那样,消息可包含地址,该地址可规定:城市=“雷蒙德市”、州=“华盛顿州”、邮递区号=“98052”。该信息语法上是有效的(即包括城市、州,并且邮递区号对于美国地址来说是正确的),并且实质上它也是有效的(即事实上98052是华盛顿州雷蒙德市的正确的邮递区号)。然而,应注意到,从地址的语法上没有办法确定该地址实质上是否有效。例如,“雷蒙德市,华盛顿州19103”是语法上有效的,但是实质上却是无效的,因为19103是宾夕法尼亚州费城的邮递区号,而不是华盛顿州雷蒙德市的邮递区号。从而,确保XML消息符合某一模式仅可确保语法有效性,而不能确保其它类型的有效性。本发明提供了一种用于对XML消息进行任意的有效性测试的框架。
图5示出了示例性的验证表500,它规定了要对某一类型的XML消息进行的验证测试。表500中示出的元素对应于树400(示于图4)的元素类型,即树400具有名为A、A1、A11等的元素,因此表500也是同样。验证表500包括四列502、504、506和508。对于验证表500的给定一行,诸条目具有下述含义:
—列502中的条目是该行所应用于的元素名;
—列504中的条目指示出对该元素规定的代表(delegate)是否是“排他的”。(术语“代表”和“排他的”将在下面特别解释);
—列506中的条目是当遇到元素时将调用的代表(或“处理程序”)的名称;以及
—列508中的条目是在元素及其全部子树都被处理之后将调用的代表。从而,表500中的第一行指示出,对于名为“A”的元素,当遇到该元素时将调用名为“fA”的代表,以及当验证了该元素的所有子树之后,要调用名为“postfA”的代表。此外,该行指示出该行中规定的代表不是“排他的”,即它们不排除对子树代表的便用。
“代表”是执行对某一类型的元素的验证的指定的代码片段。例如,用于图2中所讨论的CITYSTATEZIP元素的代表可包含(或至少参考)美国城市、州和邮递区号的表,来判断CITYSTATEZIP元素中指定的组合是否是正确的组合。要理解到本发明不限于任何特定类型的验证测试,结合了本发明的系统的用户可自由地编写他们自己的代表,并定义其使元素有效的含义。尤其是,应观察到,代表不限于考虑登记的元素的内容(或甚至是登记的子树的内容),而是还可考虑该子树外的信息(例如,用于CITYSTATEZIP元素的代表还可考虑街道地址(图2和3所示的元素204),以便判断zip+4值是否正确)。根据编写了什么代表可任意地定义有效性这个事实对验证任何类型的消息都提供了灵活性。
虽然将理解到根据本发明的系统可配置成使用任何指定的代码片段作为代表,但是在一个例子中,以诸如C#之类的编程语言来编写代表。
代表名在列506和列508中都出现。列506中命名的代表是在树遍历中访问一给定元素时将调用的代表。列508中命名的代表将在遍历了该元素的所有子树后被调用。从而,列508中命名的代表是“后处理程序”,因为它是在该元素及其所有子树都被访问之后被调用的。
列504中规定的“排他的”属性规定了对于当前元素的子树是否要调用代表。从而,在表500中,元素A2具有排他属性,意味着,当遇到类型A2的元素时,就不调用用于A2的子树的元素的个别代表,因为A2的代表具有对A2及其所有子树的“排他的”控制。从而,即使表500示出了用于元素A21和A22的代表,也不调用这些代表,因为A2具有“排他的”属性,防止了对A2的任一子树的任何元素调用代表。
根据本发明的系统可包含一种验证引擎,它走查XML消息(如以深度优先顺序遍历该消息所表示的树),并根据验证表中的规定应用代表。将理解到,验证引擎允许修改或替换验证测试,而无需访问验证引擎的源代码;可简单地通过从验证表中登记或解除登记代表,来改变验证测试。这种不用访问底层的验证引擎源代码就能修改验证测试的能力是本发明所提供的灵活性的一个实例。
表1示出了使用验证表500,通过验证引擎对树400(示于图1)执行的示例性验证测试。左边的列以事件出现的顺序示出了验证过程中的各种事件(如遇到元素以及完成元素的子树)。右边的列示出了根据发生的事件而调用哪个代表。如表1所示,即使元素A21和A22具有为其登记的代表,验证引擎也不调用这些代表,因为A21和A22是节点A2的孩子,且所登记的A2的排他标记设置为“是”。(如果在一不同的消息中,A21或A22是未标记为排他的某一另一节点的孩子,则验证引擎将遇到节点A21或A22,且在遇到这些节点时将调用代表fA21orA22)。
表1
引擎所遇到的元素 |
调用的代表 |
A |
fA |
A1 |
fA1 |
A11 |
fA11 |
A11处的子树处理完毕 |
(后处理程序为空,所以不调用) |
A12 |
fA12 |
A12处的子树处理完毕 |
postfA12 |
A1处的子树处理完毕 |
(后处理程序为空,所以不调用) |
A2 |
fA2 |
A2处的子树处理完毕(fA2是排他的) |
postfA2 |
A3 |
(处理程序为空,所以不调用) |
A31 |
fA31 |
A31处的子树处理完毕 |
(处理程序为空,所以不调用) |
A32 |
(无登记,所以不调用) |
A32处的子树处理完毕 |
(无登记,所以不调用) |
A3处的子树处理完毕 |
postfA3 |
A处的子树处理完毕 |
postfA |
根据本发明的一个特征,可以有全局验证表和局部验证表。本发明的体系结构允许这种可能性,即字段或字段组可在若干不同类的消息之间共用。这些公共字段的设置可存储在全局验证表中。仅应用于某一特定类的消息的任何设置可存储在局部验证表中。实际上,局部验证表充当全局验证表的一组类特定的置换。并且,在本发明的一个实施例中,可创建多个全局验证表,可根据某一上下文环境来选择某一特定的全局表来使用。
示例性验证过程
如上所述,根据本发明的验证引擎走查XML消息,根据一个或多个验证表对消息中的各种元素调用代表。下文是对验证引擎所执行的过程的描述。
验证引擎以XML消息的根元素(如图2至3的例子中的ADDRESS元素,或图4的例子中的“A”元素)为起始。该起始元素设置成“当前”元素。然后,对于当前元素(在该说明中称为“X”),验证引擎:
—在局部验证表中对X查找“元素处理程序”列中的代表。如果该局部验证表中的该列中规定了代表,则引擎调用元素处理程序。
—如果局部表没有在“元素处理程序”列中对X规定代表,则引擎在全局表中查找用于X的代表。如果在全局表中的“元素处理程序”列中规定了用于X的处理程序,则调用该规定的代表。如果任一表中都没有规定用于元素X的代表,则没有用于元素X的代表被调用。
—对于元素X的每个孩子元素,重复上述步骤(除非X登记为“排他的”)。在一个实施例中,这些步骤以递归函数来实现,可在元素X的子树上调用。
—如果对于X存在后处理程序代表(局部表中或全局表中),则在处理了X的所有子树后,调用后处理程序。(如果在两种表中都存在用于X的后处理程序代表,则仅调用局部表中规定的代表)
图6以流程图的形式示出了验证引擎执行的过程。一开始,定义“当前节点”为树的根节点(602)(如XML消息中的根元素)。然后参考局部验证表。如果在局部验证表中对于该当前节点存在的条目示出用于该节点类型的代表(604),则从局部验证表使用该条目(606)。如果局部验证表中没有条目,则判断全局验证表中是否有条目(607)。如果全局验证表中有条目,则使用该条目(608)。假设在局部验证表或全局验证表中找到了某个代表,则调用该代表(610);否则过程如下述那样进行到614。
如果对于当前节点的条目(即来自局部或全局验证表(不论实际上使用哪一个表)的条目)指示出该条目不是“排他的”(612),则图6的过程在当前节点的每个孩子节点上被递归调用(614)。较佳地,以从左至右的顺序对这些孩子节点调用所述过程。如果对于当前节点的条目指示出该条目是排他的,则图6的过程不对孩子节点调用,因为当前节点的条目对该当前节点的所有自由有排他控制。
如果对当前节点有后处理程序代表(616),则调用该后处理程序(618)。(该后处理程序或者直接在610处调用的代表之后应用(在当前节点条目是排他的情况下),或者在处理了子树之后应用(在当前节点条目不是排他的情况下))。在应用了后处理程序代表(或已判断出没有后处理程序代表之后),判断当前节点是否是顶层树的根(620)。如果当前节点是顶层树的根(如图3中的节点302,或图4中的节点“A”),则过程终止。否则,过程返回到其调用调用程序(因为如果当前节点不是顶层根,则图6的过程已有该过程的在先实例所递归调用)。
注意到已给出的上述例子仅仅用于解释的目的,而不应被解释成对本发明的限制。虽然参考了各种实施例来描述了本发明,但是理解到这里所使用的词语仅仅是说明和例示用的词语,而不是限制性的词语。此外,虽然这里参考特定的手段、材料和实施例来描述了本发明,但是本发明不打算限制于这里所揭示的任何特定例,相反,本发明扩展到如本发明的范围之内的所有功能上相当的结构、方法和使用。能够从本说明书中获益的那些本领域的技术人员可进行各种修改,可作出各种修改而不背离本发明的范围和要旨。