一种基于标记的xml快速解码方法

文档序号:6519460阅读:134来源:国知局
专利名称:一种基于标记的xml快速解码方法
技术领域
本发明涉及基于XML(eXtensible Markup Language)数据格式的信息解码方法。
背景技术
XML(扩展标记语言)是一种置标语言,由于其具有开放性、可扩展性、语法严格、支持异构网络数据交换、安全性等强大优势,目前广泛应用于网络数据通信、电子商务、图书出版等关键性行业。在现代网络通信中采用XML数据格式定义应用层接口已经成为趋势,例如移动通信定位系统中定位客户端和定位网关之间的接口协议MLP,为了实现诸如此类的通信设备,需要在内部提供编解码功能,即从网络线路上的XML数据流到计算机内部数据结构的转换。XML本身是一种结构化的文本数据格式,主要由标记、标记值、属性、属性值、特殊处理指令等构成。
目前针对XML数据解析技术有如下两种方案一种是先直接采用现存的专门用于解析XML数据的支持包(例如JAVA语言中的javax.xml.parsers)来提取结构和文本信息,然后通过编程语言(如C、C++等)定义树型数据类型,对这些结构和文本信息进行存放,最后根据得到的树进行遍历操作,从而转换为最终的数据结构,并输入到应用程序中进行相关处理;另一种是不借助任何现有的支持包,完全自行实现对输入的XML格式信息进行结构和文本信息的提取,以后的步骤如同前面一种方案。
很显然,由于以上两种方案都离不开定义复杂的树型数据结构,并且离不开执行树的构造和遍历操作,从而严重影响了系统性能。另外一个方面就是目前在通信系统的实现过程中,为了符合软件工程思想,保证代码的共用性和模块化也是非常关键的。对于接口消息解码思路是将消息分为两个层次,即消息级和IE(信息元素)级,真正核心代码实现位于IE级。这样存在一个很大的缺陷,从软件工程角度看就是可扩展性不够好,例如对消息IE进行了更改或者增删,就不得不去修改核心代码。而且,核心解码代码与接口绑定在一起,使得这种核心代码本身没有任何的移植性。对于不同的接口,不得不去分别开发不同的核心解码代码,从而增加了系统开发成本。

发明内容
根据上述背景技术中分析的缺陷和不足,本发明目的在于克服上述缺陷,提供了一种非常简洁而高效的基于标记的XML快速解码方法。
本发明的技术方案是一种基于标记的XML快速解码方法,包括解析和解码,其特征在于标记规则结构信息通过段标记来体现,内容信息通过值标记来体现;标记插入规则在每一段内,必须至少有一个值标记ValTag,而且至多只能有一个值标记ValTag;段定义和分段方法对于每个XML元素的值或属性各自分为一段;如果元素没有属性和值就不分段;解码规则严格按照段的顺序执行、不能跳跃;对于消息中必选的IE或者属性,不执行段内搜索过程;对于消息中可选的IE或者属性,必须执行段内搜索过程;解析步骤如下按照段和值标记插入规则解析成带标记的平面的流,结构信息通过段标记来体现,内容信息通过值标记来体现;解码步骤如下解析对带有标记的平面的流①获取当前段的长度;②在当前段内检查IE是否存在;③在当前段内提取IE的值。
本发明的有益效果如下本发明采用了标记方法,并通过引入段的概念避免了树型数据结构的引入,同时也大大缩小了搜索范围,从而大大增加了解码速度。另外对消息解码进行了更进一步的分层设计,在原来两层的基础上,进一步分为消息级、IE级和段级,使得和核心解码代码转移到与IE本身没有任何绑定关系的段级,从而使得核心解码程序一旦开发出来,适用于任何基于XML的接口消息解码实现,无疑这将大大加快系统开发进度,减少了代码开发量和开发成本。
在如下的具体实施方案里面,将详细阐述本发明以上的四个主要方面。


图1是本发明的基于XML消息解码实现和测试总框架。
图2是本发明的XML数据解析部分。
图3是本发明的流数据解析部分。
图4是本发明的XML数据解析流程图。
图5是本发明的带标记流解码的总体框架图。
图6是本发明的段解码示意图。
具体的实施方式(1).基于XML新的解码思路以下结合附图对本发明作进一步的详细说明。注意为了突出本发明内容,将忽略该领域技术人员熟悉的XML技术基础知识、消息解码所涉及的基本内容,如网络字节顺序转换等。
参见附图1,XML数据生成模块11用于仿真生成原始数据,是整个系统的输入,该模块主要用于系统的测试。解析模块10是本发明的核心部分,包括两个子系统101和102,参见附图2和附图3,分别用于对XML的解析并插入标记和对带标记的流进行解码。数据业务应用模块12作为整个系统测试的输出,主要为了验证整个设计方案的可行性,并提供性能测试。模块101在执行XML解析过程中,按照后面将介绍的段和值标记插入规则解析成带标记的平面的流,结构信息通过段标记来体现,内容信息通过值标记来体现,这样避免了引入复杂的数据接口来实现同样的功能。在模块102实现对带标记流进行解码过程中,仅仅需要设计非常快速而简洁的段级核心解码代码即可。
(2).标记及标记插入规则针对XML技术本身的特点,携带信息的标记本身具有一定的信息量,例如对于版本号就采用ver,对于经纬对坐标就用X,Y,Z。而且因为通信接口消息的特点必选和可选IE在整个消息中出现的位置是随机的,所以在解码过程中需要采用一定的搜索算法。而为了加快执行效率,必须约束搜索的范围,以加快执行的效率。否则搜索将在整个接收缓冲区里进行,显然这是不必要的。另外,同样的IE可能在不同的位置多次出现,例如在消息头和消息体中都有ver字段,这样就更有必要对搜索的范围加以约束。而通过本发明引入标记可以非常巧妙的解决了上述问题。
为了对XML数据做一般性分析,引入典型XML数据概念,即一个典型的XML数据必须能够代表所有可能的XML消息结构。具有如下特征一是XML数据必须是结构良好的,即符合XML的严格语法规范;二是XML数据必须是合法的,即符合XML数据对应DTD约束规范;
三是在保证前面两条的前提下,必须包含XML数据组成成分元素、属性、元素值与属性值的所有可能组合。
由于接口消息和典型XML数据之间有如下对应关系,所以分析典型XML数据也就是等价于分析了所有可能的接口消息结构。
二者对应表参见下表

表1接口消息和XML数据对应表根据前面的定义,接口消息对应的典型XML消息如下所示<?xml version=“1.0” encoding=“UTF-8”?><MSG><HDR>
<TAG1>t_val1</TAG1>
<TAG11 ATTR1=“11a_val1”>t_val11</TAG11>
<TAG12>t_val12</TAG12>
<TAG121>t_val121</TAG121>
<TAG2 ATTR1=“2a_val1”ATTR2=“2a_val2”>t_val2</TAG2>
<TAG3 ATTR1=“3a_val1”/>
<TAG4/></HDR><BODY>……</BODY><MSG>
从结构上看,可以知道MSG是整个XML消息的根元素,下面有两个一级子元素,分别是消息头HDR和消息体BODY。HDR又有三个子元素,分别是TAG1,TAG2,TAG3和TAG4,其中TAG3和TAG4是空元素,即不带内容信息。而TAG1又具有两个子元素TAG11和TAG12,TAG12有一个子元素TAG121。同样,在子元素BODY里面,同样有类似的迭代关系构成整个结构化的数据。
从信息内容上看TAG1,TAG11,TAG12,TAG121,TAG2都携带了信息,分别是t_val1,t_val11,t_val12,t_val121,t_val2。另外TAG11和TAG2都带有信息内容(属性值)分别是11a_val1,2a_val1,2a_val2和3a_val1。
正如前面所述,考虑到消息某些IE可选,所以除了提取XML数据的信息内容,有必要保留必要的结构信息。在这个原则下,引入两个标记值标记(valTag)和段标记(segTag),分别用于反映输入XML数据信息的内容和结构。选择标记时遵从节约和小概率原则,节约指尽可能占用少的字节数目,因为每个消息平均估算40个左右,如果一个标记占用字节数目为n,那么平均每条消息将占用(40×n)个字节,所以尽量让n的值偏小。小概率原则是在确定了标记长度之后,选择在消息内容里面不太可能出现的字符作为标记。因为标记本身并不是原始信息内容,它唯一的作用是用于辅助表达原始流里面的结构信息。否则,必须针对原始信息内容里出现了标记做出特殊的处理。
对于标记的定义和原则进行确定后,下面阐述标记插入规则,为了举例说明,不防假设ValTag为“=”,SegTag为“|”。
对于值标记ValTag来说,插入的规则为只需要在每次遇到信息内容之前插入一个,如“t_val1”就转换为“=t_val1”,“t_val11”转换为“=t_val11”,其他依此类推。
对于段标记SegTag来说,插入的规则为在每一段内,必须至少有一个值标记ValTag,而且至多只能有一个值标记ValTag。
因为一个结构良好且合法的XML消息一定是由根元素通过父子迭代成为一颗树型结构,这样一个典型的XML消息,可以通过对元素的分析和分类来解析整个XML文档。对于元素分类参见如下(2.1).元素没有属性,但具有值例如对于典型XML消息片断<MSG><HDR><TAG1>t_val1</TAG1>来说,对于单独的MSG或者HDR,不必要设计一个段,因为解码的最终目的是提取内容信息,而不是结构信息。所以插入标记后的流为“|MSGHDRTAG1=t_val1|”。而不是“|MSG|HDR|TAG1=t_val1|”,因为如果这样前面两段里面将没有值标记,即不含最终的内容信息,这会导致段的浪费,并给以后的解码带来了一定的困难。
(2.2).元素具有属性,又具有值例如对于典型XML消息片断<TAG1>t_val1</TAG1>
<TAG11 ATTR1=“11a_val1”>t_val11</TAG11>
插入标记后为“|TAG1=t_val1|TAG11ATTR1=11 a_val1|=t_val11|”。如上XML数据片断包含三个信息内容,分别是t_val1,11a_val1和t_val11,由此可以看出段的数目与值的个数是一致的。对于一个元素具有多个属性的情况,根据前面的段标记插入规则将为每个属性产生一个单独的段。
(2.3).元素具有属性,没有值这种情况主要是空元素,例如对于典型XML消息片断<TAG3 ATTR1=“3a_val1”/>
插入标记后为“|TAG3ATTR1=3a_val1|”(2.4).元素没有属性,没有值这种情况同样是针对空元素,例如对于典型XML消息片断<TAG4/>
由于不能提取任何信息内容,所以不会对此生成单独的段,即空元素将被忽略。综合以上四种情况,不难得到整个典型的XML消息的经过标记插入以后,得到的带标记的流为“|MSGHDRTAG1=t_val1|TAG11ATTR1=11a_val|=t_val11|TAG12=t_val12|TAG121=t_val121|TAG2ATTR1=2a_val1|ATTR2=2a_val2|=t_val2|TAG3ATTR1=3a_val1|”。
(3).对XML数据的解析根据(2)中对标记和标记插入规则的分析,以及需要得到的带标记的流,并充分利用XML消息本身具有迭代的特点,即站在任何一个层次的元素节点上面,总可以找到一个通用的算法,可以向上(父节点方向)或者向下(子节点方向)进行递归,从而遍历到整个的XML文档。对于解码来说,显然采用向下策略要简便。由此可见,对于XML的解析核心部分就是迭代算法的设计。参见附图4所示的XML解析流程图(迭代算法),下面予以详细的说明首先通过块401计算当前节点的类型,经过402的判断如果为根元素,那么不可能有属性值,也不可能是最内层的元素节点,所以不执行流构造操作,而是如块403所示返回执行迭代解析函数本身。
如果当前节点的类型为一般的元素节点,则按照块404提取该节点,并按照405所示,开始构造输出流。
接着如块406所示获取当前节点的属性列表,并通过块407的判断是否具有属性。如果有属性,那么根据408所示,执行循环操作,每次操作构造一个属性段,构造的段内容如409所示分别为属性名称,值标记,属性值和段标记。注意构造输出流是采用追加的方式,即对于每个节点,段的开始总是从块405开始构造,然后进行追加。所谓追加就是指从前往后按照顺序存放,不留空隙也不重叠。由于是迭代的方式,那么整个XML文档的流输出也一致的采用了追加的方式。如果407判断当前节点没有属性,或者408循环操作完毕,那么开始如块410所示计算节点的子节点,并通过411判断当前节点是否为最内层节点,即是否还具有子节点。如果是,那么就构造信息内容段,构造方式如块415所示分别是值标记、信息内容和段标记。如果411判断当前节点不是最内层的节点,那么还不能构造段,而是按照403所示调用迭代的解析函数本身。
(4).对带标记流的解码整个解码系统的目标是生成最后的数据结构,考虑到接口消息的特点如下一是所有消息共用一个消息头,对于不同消息只是某些IE取值不同;二是所有消息都共用大量的IE。
根据这两个的特征,并根据软件工程对代码最大重用性的原则,设计如附图5所示的总体解码框架示意图,总体解码思路就算消息头和消息体分离;消息体实行分级策略分为消息级、IE级和段级。从附图5可以看出,IE级相当是对消息的分解,所以其总的模块数目大概是消息数量的4到5倍,而段级又起到了收敛的作用,这样整个解码的核心部分实际就是如下三个功能性的模块一是获取当前段的长度;二是在当前段内检查IE是否存在;三是在当前段内提取IE的值。
其它级(消息和IE级)只是一种程序的框架而已,这使得程序设计非常简便,而且非常容易维护和具有良好的扩展性,无论以后增加多少个消息或者IE,都只需要如上的三个段级功能模块。
为了说明的方便性,将(3)里面典型的XML数据最终输出的带标记的流作如下等价变换,得到附图6所示的内容一是将TAG全部等价写成IE,因为MLP协议里面的IE名称就对应于XML文档的标签;二是将段标记用一条长的竖线代替。
为了便于说明,现在以附图6来阐述段解码过程。消息开始的三个IE分别是IE1,IE11和IE12,其中IE1和IE11是必选,IE12是可选。而IE11具有一个可选的属性ATTR1。
首先段1对应必选的IE1,直接取出t_val1即可。紧接者,解析段2,由于已经知道段1(IE1)之后就是下一个IE11,并且该IE具有一个可选的属性,此时需要判断是否存在,然后才能提取里面的值。这里仅仅通过在段2的范围内部做个搜索即可。如果存在ATTR,那么提取值赋值给数据结构对应的变量,而下一段仍然是IE11的内容,同样提取里面的值即可。相反,如果在IE11段内没有找到ATTR,那么说明可选的属性为空缺,该段的值就是IE11的取值。这样就对必选的IE11解码完毕。接着开始解码IE12,由于该IE是可选的,所以同样要在该段内执行搜索,以判断该IE是否存在。依此类推,当整个消息IE对应的段全部解码完毕,整个消息也就解码完毕。
基于上一段的详细描述,得到对带标记流的解码需要遵从如下规则一是对于输入流来说,必须按照严格的顺序逐段解码,不能跳跃。
二是对于必选IE或者属性,为了提高解码效率,不需要执行段内搜索。
三是对于可选IE或者属性,必须执行段内搜索,从而决定是否存在解码的对象。
这样,对于任何段的解码,从程序设计的角度来看,结合上面的解码规则,只需要实现前天提到的三个段级的功能模块即可,阐述如下(4.1).获取段的长度这已经简单到在一个字符串里面去如何快速搜索到段标记segTag。采用优化的库函数,当然为了避免在整个接收缓冲区中搜索,不妨约定最大的搜索范围,如何越界就视为失败。在本发明中,采用了监哨所策略,这样避免在循环中每次去检测是否达到搜索边界,从而在一定程度上加快了搜索速度。
(4.2).在当前段内检查IE是否存在这也是在段内执行子字符串搜索,同样使用经过优化的库函数。
(4.3).在当前段内提取IE的值只需要在当前段内,将值标记和下一个段标记之间的串取出即可。
经过如上阐述,可以看出对段的解码已经简化到对字段串的基本操作,由于这三个模块是整个解码的核心,需要被频繁调用,所以本发明采用了优化的库函数和自行实现相结合的策略,从而达到了系统设计目的。
权利要求
1.一种基于标记的XML快速解码方法,包括解析和解码,其特征在于标记规则结构信息通过段标记来体现,内容信息通过值标记来体现;标记插入规则在每一段内,必须至少有一个值标记ValTag,而且至多只能有一个值标记ValTag;段定义和分段方法对于每个XML元素的值或属性各自分为一段;如果元素没有属性和值就不分段;解码规则严格按照段的顺序执行、不能跳跃;对于消息中必选的IE或者属性,不执行段内搜索过程;对于消息中可选的IE或者属性,必须执行段内搜索过程;解析步骤如下按照段和值标记插入规则解析成带标记的平面的流,结构信息通过段标记来体现,内容信息通过值标记来体现;解码步骤如下解析对带有标记的平面的流①获取当前段的长度;②在当前段内检查IE是否存在;③在当前段内提取IE的值。
全文摘要
本发明提出了一种基于标记的XML快速解码方法,通过定义典型XML数据模型,引入段标记和值标记以最小的代价分别描述了XML数据文档的结构和内容信息,并提出了标记选择规则和标记插入规则,从而避免定义复杂的数据结构,大大加快了解码效率。同时为了解码模块的高度可移植性,在现在广泛应用的二级分层(消息和IE级)基础上,创造性的提出了三级分层(消息、IE和段级)模型,从而可以明显增加解码核心模块的共用性和可扩展性,从而大大节省了系统开发成本。
文档编号G06F17/30GK1667610SQ20051001842
公开日2005年9月14日 申请日期2005年3月24日 优先权日2005年3月24日
发明者廖祥龙, 郑亮 申请人:北京北方烽火科技有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1