发明内容
鉴于现有技术的不足,本发明提供了一种XML报文中节点的划分方法,如下:
步骤A1,获取当前位置和当前位置的值;
步骤A2,判断当前位置的值是否超过了所述XML报文的总长度或者为负数,如果当前位置的值超过了所述XML报文的总长度或者为负数,返回错误,否则,执行步骤A3;
步骤A3,判断当前位置对应的字符是否为“<”或“>”,如果是,执行步骤A5,如果不是,执行步骤A4;
步骤A4,将当前位置移动一个单位,并将移动一个单位后得到的字符的位置作为当前位置,返回执行步骤A2;
步骤A5,将当前位置作为当前节点的节点边界,并将当前位置移动一个单位,将移动一个单位后得到的字符的位置设置为当前位置;
步骤A6,判断当前位置的值是否超过了所述XML报文的总长度或者为负数,如果当前位置的值超过了所述XML报文的总长度或者为负数,返回错误,否则,执行步骤A7;
步骤A7,判断当前位置对应的字符是否为“<”或“>”,如果是,执行步骤A8,如果不是,将当前位置按与步骤A5中当前位置移动方向相同的方向移动一个单位,将移动一个单位后得到的字符的位置作为当前位置,返回执行步骤A6;
步骤A8,将当前位置作为当前节点的另一个节点边界,得到当前节点,所述节点边界包括节点头和节点尾。
优选地,所述当前位置的值为当前位置的字符相对于所述XML报文起始位置的偏移。
相应地,所述当前节点使用一个二元组进行表示,所述二元组包括所述当前节点的节点头和节点尾,在所述二元组中,使用所述当前节点的节点头相对于所述XML报文中起始位置的偏移表示所述节点头,使用所述当前节点的节点尾相对于所述XML报文中起始位置的偏移表示所述节点尾。
优选地,步骤A4具体的包括:
将当前位置向前移动一个单位,并将所述向前移动一个单位后得到的字符的位置作为当前位置,并将表示当前位置的值递减1,返回执行步骤A2;
或,
将当前位置向后移动一个单位,并将所述向后移动一个单位后得到的字符的位置作为当前位置,并将表示当前位置的值递增1,返回执行步骤A2。
优选地,步骤A5具体的包括:
将当前位置作为当前节点的节点头,并将当前位置向后移动一个单位,将向后移动一个单位后得到的字符的位置设置为当前位置,并将表示当前位置的值递增1;
或,
将当前位置作为当前节点的节点尾,并将当前位置向前移动一个单位,将向前移动一个单位后得到的字符的位置设置为当前位置,并将表示当前位置的值递减1。
相应地,当步骤A5中,将当前位置作为当前节点的节点头,并将当前位置向后移动一个单位时,步骤A7具体的为:
判断当前位置对应的字符是否为“<”或“>”,如果是,执行步骤A8,如果不是,将当前位置向后移动一个单位,将向后移动一个单位后得到的字符的位置作为当前位置,并令表示当前位置的值递增1,返回执行步骤A6。
相应地,当步骤A5中,将当前位置作为当前节点的节点尾,并将当前位置向前移动一个单位时,步骤A7具体的为:
判断当前位置对应的字符是否为“<”或“>”,如果是,执行步骤A8,如果不是,将当前位置向前移动一个单位,将向前移动一个单位后得到的字符的位置作为当前位置,并令表示当前位置的值递减1,返回执行步骤A6。
相应地,当步骤A5中,将当前位置作为当前节点的节点头,并将当前位置向后移动一个单位时,步骤A8具体的为:
将当前位置作为当前节点的节点尾,得到当前节点。
相应地,当步骤A5中,将当前位置作为当前节点的节点尾,并将当前位置向前移动一个单位时,步骤A8具体的为:
将当前位置作为当前节点的节点头,得到当前节点。
优选地,所述将当前位置移动一个单位为由当前字符的位置移动一个字符的距离。
通过上述一种XML报文中节点的划分方法,本发明可以实现一种XML报文中节点类型判断方法,具体的为:
步骤B1,判断当前节点是否为以“<”开头,以“>”结尾,如果是,执行步骤B2,如果不是,执行步骤B7;
步骤B2,判断当前节点中字符“<”之后的第一个位置对应的字符,如果为“?”,执行步骤B3,如果为“!”,执行步骤B4,如果为“/”,执行步骤B5,否则,执行步骤B6;
步骤B3,判断当前节点中字符“>”之前的位置所对应的字符是否为“?”,如果是“?”,判断当前节点中“<”之后的下一个位置的“?”与“>”之前第一个位置的“?”是否重合,如果不重合,则记录当前节点为XML报文的头,如果重合,返回错误,如果不是“?”,报文错误;
步骤B4,记录当前节点为不需要解析的部分;
步骤B5,记录当前节点为元素尾;
步骤B6,判断当前节点中字符“>”前的一个字符是否为“/”,如果是,则当前节点为一个完整的元素,否则,当前节点为一个元素的元素头;
步骤B7,判断当前节点是否以“>”开头,以“<”结尾,如果是,则记录当前节点为元素中间的值,如果不是,返回错误,结束判断节点类型。
通过上述一种XML报文中节点的划分方法,本发明可以实现一种XML报文中定位元素的方法,具体的包括:
步骤C1,判断当前节点的类型,如果是完整的元素,执行步骤C2,如果是元素头,执行步骤C3,如果是元素尾,执行步骤C5,如果是元素中间的值,执行步骤C7,如果是不需要解析的部分,执行步骤C8,如果是报文头,返回错误;
步骤C2,记录当前节点所属的元素即为所述步骤C1中的完整的元素;
步骤C3,划分得到当前节点的下一个节点,并设为第一节点;
步骤C4,判断第一节点的节点类型:
如果是元素尾,判断第一节点中的元素名称与当前节点的元素名称是否相同,如果相同,则当前节点所属的元素为以当前节点为元素头、第一节点为元素尾组成的元素,如果不相同,则划分得到第一节点的下一个节点,并设为第一节点,返回重新执行步骤C4;
如果是元素头,判断第一节点中的元素名称与当前节点的元素名称是否相同,如果相同,则返回错误,结束对所述XML报文的解析,如果不相同,划分得到第一节点的下一个节点,并设为第一节点,返回重新执行步骤C4;
如果是元素中间的值,划分得到第一节点的下一个节点,并设为第一节点,返回重新执行步骤C4;
步骤C5,划分得到当前节点的上一个节点,并设为第二节点;
步骤C6,判断第二节点的节点类型:
如果是元素头,判断第二节点中的元素名称与当前节点的元素名称是否相同,如果相同,则得到当前节点所属元素为以第二节点为元素头、当前节点为元素尾组成的元素,如果不相同,划分得到第二节点的上一个节点,并设为第二节点,返回重新执行步骤C6;
如果是元素尾,判断第二节点中的元素名称与当前节点的元素名称是否相同,如果相同,返回错误,结束对所述XML报文的解析,如果不相同,则根据所述预先约定的节点划分方法,划分得到第二节点的上一个节点,并设为第二节点,返回重新执行步骤C6;
如果是元素中间的值,划分得到第二节点的上一个节点,并设为第二节点,返回重新执行步骤C6;
步骤C7,划分得到当前节点的上一个节点,设为第三节点,划分得到当前节点的下一个节点,设为第四节点,并判断第三节点和第四节点的类型:
如果第三节点和第四节点都是元素头,则第三节点和当前节点属于同一个元素,根据第三节点和当前节点向后划分得到第五节点,则得到当前节点所属的元素为以第三节点为元素头、第五节点为元素尾的元素;
如果第三节点和第四节点都是元素尾,则第四节点和当前节点属于同一个元素,根据第四节点和当前节点向前划分得到第六节点,则得到当前节点所属的元素为以第六节点为元素头、第四节点为元素尾的元素;
如果第三节点为元素头、第四节点为元素尾,判断第三节点中的元素名称与第四节点中的元素名称是否相同,如果相同,则当前节点所属的元素为以第三节点为元素头、第四节点为元素尾组成的元素,如果不相同,返回错误;
如果第三节点为元素尾、第四节点为元素头,返回错误;
步骤C8,划分得到当前节点的下一个节点,并设为当前节点,判断当前节点是否为需要解析的部分,如果是,返回步骤C1,如果不是,重复执行本步骤操作,直到当前节点超出所述XML报文的范围。
优选地,所述根据第三节点和当前节点向后划分得到第五节点,具体的包括:
步骤C8-a,划分得到当前节点的下一个节点,并设为第五临时节点;
步骤C8-b,判断第五临时节点是否为元素尾,如果是,执行步骤C8-c,如果不是,继续划分得到第五临时节点的下一个节点,并设为第五临时节点,返回重新执行步骤C8-b;
步骤C8-c,判断第五临时节点中的元素名称与第三节点中的元素名称是否相同,如果相同,则将第五临时节点记录为第五节点,如果不相同,划分得到第五临时节点的下一个节点,并设为第五临时节点,返回重新执行步骤C8-b。
优选地,所述根据第四节点和当前节点向前划分得到第六节点,具体的包括:
步骤C8-a’,划分得到当前节点的上一个节点,并设为第六临时节点;
步骤C8-b’,判断第六临时节点是否为元素头,如果是,执行步骤C8-c’,如果不是,继续划分得到第六临时节点的上一个节点,并设为第六临时节点,返回重新执行步骤C8-b’;
步骤C8-c’,判断第六临时节点中的元素名称与第四节点中的元素名称是否相同,如果相同,将第六临时节点记录为第六节点,如果不相同,则执行步骤划分得到第六临时节点的上一个节点,并设为第六临时节点,返回重新执行步骤C8-b’。
通过上述一种XML报文中节点的划分方法,本发明可以实现一种XML报文中定位当前元素的第一个子元素的方法,具体的包括:
步骤D1,从当前元素的元素头的节点开始,划分得到当前元素的元素头的节点的下一个节点,并设为第七节点;
步骤D2,判断第七节点的位置是否超出了当前元素的元素尾,如果是,返回错误,如果不是,判断第七节点的类型:
如果是元素头,并且第七节点包含的元素名称与当前元素的元素名称不同,则第七节点为当前元素的第一个子元素的元素头,执行步骤D3;
如果是元素尾,执行步骤D4;
否则,执行步骤D5;
步骤D3,由第七节点定位得到当前元素的第一个子元素;
步骤D4,判断第七节点与当前元素的元素尾是否重合,如果是,则当前元素没有子元素,如果不是,则返回错误;
步骤D5,划分得到第七节点的下一个节点,并设为第七节点,返回重新执行步骤D2。
通过上述一种XML报文中节点的划分方法,本发明可以实现一种XML报文中相邻元素的定位方法,具体的包括:
步骤E1,判断当前元素是否为根元素,如果是,则当前元素没有根元素,如果不是,执行步骤E2;
步骤E2,根据预先约定的父元素定位方法,查找当前元素的父元素,并定位当前元素的父元素的位置;
步骤E3,根据所述预先约定的节点划分方法,划分得到当前元素的元素尾的下一个节点,并设为第八节点;
步骤E4,判断第八节点是否超出当前元素的父元素的范围:
如果是,停止对当前元素的相邻元素的查找;
如果不是,判断第八节点的节点类型,如果是元素头,则第八节点为当前元素的相邻元素的元素头,根据预先约定的元素定位方法,得到当前元素的相邻元素,否则,根据所述预先约定的节点划分方法,划分得到第八节点的下一个节点,设为第八节点,返回重新执行步骤E4。
优选地,所述预先约定的父元素定位方法,具体的包括::
步骤E2-1,判断当前元素是否为根元素,如果是,则当前元素没有父元素,如果不是,执行步骤E2-2;
步骤E2-2,划分得到当前元素的元素头的上一个节点,并设为第九节点;
步骤E2-3,判断第九节点的类型,如果是元素头,执行步骤E2-4,否则,执行步骤E2-5;
步骤E2-4,第九节点为当前元素的父元素的元素头,根据所述预先约定的元素定位方法,由第九节点定位得到当前元素的父元素;
步骤E2-5,划分得到第九节点的上一个节点,并设为第九节点,返回步骤E2-3。
通过上述一种XML报文中节点的划分方法,以及基于上述节点划分方法的节点类型判断方法、定位元素方法、定位当前元素的第一个子元素的方法、相邻元素的定位方法,本发明可以实现一种XML报文的解析方法,具体的包括:
步骤F1,获取XML报文中的根元素,将所述根元素设为当前元素;
步骤F2,判断当前元素是否有子元素,如果有,执行步骤F3,如果没有,执行步骤F4;
步骤F3,查找当前元素的第一个子元素,将所述第一个子元素设为当前元素,返回步骤F2;
步骤F4,判断当前元素之后是否有相邻元素,如果有,执行步骤F5,如果没有,执行步骤F6;
步骤F5,定位并获取当前元素的相邻元素,将所述当前元素的相邻元素设为当前元素,返回步骤F2;
步骤F6,将当前元素的父元素设为当前元素,并判断当前元素是否为根元素,如果是,执行步骤F7,如果不是,返回步骤F4;
步骤F7,所述XML报文解析完毕。
本发明实施例提供的技术方案带来的有益效果是:一种XML报文中节点的划分方法,以及基于上述节点划分方法的节点类型判断方法、定位元素方法、定位当前元素的第一个子元素的方法、相邻元素的定位方法、XML报文的解析方法,本发明提供的解析方法适合使用C语言实现,可以应用于嵌入式环境中,并且不需要建立节点树,占用内存小。
具体实施方式
下面结合附图和具体实施例对本发明作进一步说明,但不作为对本发明的限定。
以下实施例提供了对XML报文中的节点进行划分及其对其应用的方法,其中,对节点进行划分的方法的应用包括节点类型判断、定位元素方法、定位当前元素的第一个子元素、定位相邻元素、XML报文的解析。
为了便于说明,以下提供了如下一段XML报文,实施例1到实施例5均为以此XML报文进行说明:
为了便于说明,在本发明中对报文中的数据形式做如下定义:
将XML报文中以“<”开头、以“>”结尾的字符串或以“>”开头、以“<”结尾的字符串定义为一个节点,例如:“<SignData>”为一个节点,”“>12345<”也为一个节点,特别地,以<?xml开头的节点为XML报文的头,例如:节点“<?xml version=″1.0″encoding=″utf-8″?>”为本实施例所提供的XML报文的头;
将形如“<Amount name=″金额:″>1000.5</Amount>”的字符串定为为一个元素,元素至少由一个节点组成,在上述元素中,由三个节点组成,完整的元素应包括元素头、值、元素尾,在上述元素中,“<Amount name=″金额:″>”为元素头,1000.5为值,“</Amount>”为元素尾,在一个元素的元素尾中“</”和“>”之间的字符串为该元素的名称,在该元素中,可以将该元素称为元素Amount,1000.5为一个文本节点,因此,上述元素可以说成是元素Amount拥有一个值为1000.5的文本节点,需要注意的是,1000.5不是元素Amount的值,在上述元素中,“name=″金额:″”为元素属性,并且元素属性只能存在于元素头中;
其中,元素可以进行嵌套,一个元素应该以“<元素名称”开头,“</元素名称>”结尾,例如在上述XML报文中,元素SignData中嵌套有元素TradeType、SubType、Timestamp、Fields,元素Fieids中嵌套有元素PayerAcNo、PayeeAcNo、Amount、TranDate、JnlNo;
XML报文可以解析为元素树,为了便于了解XML报文的结构,使用元素树表示上述XML报文,如图1;
实施例1
在本实施例中,提供了一种对XML报文中的节点进行划分的方法,根据此方法,可以在XML报文的任意位置开始对XML报文进行扫描,完成节点的划分过程,参见图2,具体的如下:
步骤101,获取当前位置和当前位置的值;
在本发明中,进行如下约定,给定一个XML报文,“位置”指的是相对于报文起始处的偏移量,“向前移动”指的是偏移量减小,“向后移动”指的是偏移量增加,优选地,向前移动使用“-1”表示向前移动一个字符,向后移动使用“+1”表示向后移动一个字符;
优选地,XML报文的起始位置即第一个字符的位置使用0表示,从起始位置向后移动一个单位得到XML报文的第二个字符,则第二个字符的位置使用1表示,依此类推,使用值和偏移可表示当前XML报文的所有位置。
在本发明中,设有当前位置,当前位置表示XML解析器正在处理的XML报文中的字符所在的位置,不固定为某一个字符,为了便于说明本实施例中将当前字符的位置的值以A进行表示;
一般地,对XML报文的解析由报文的初始位置开始,在本实施例中,以上述XML报文为例进行说明,以对XML报文的初始位置开始进行节点划分和扫描为例进行说明,因此将上述XML报文的第一个字符作为当前位置,此时A的值具体的为0;
需要说明的是,在本实施例所提供的节点划分方法,优选地以一个二元组来表示一个节点,例如二元组可以为(a1,a2),表示当前节点的位置和长度,其中,a1为当前节点的节点头的位置的值,用来表示当前节点的节点头的位置,a2为当前节点的节点尾的位置的值,用来表示当前节点的节点尾的位置,a2-a1+1即是节点的长度;
步骤102,判断当前位置的值是否超过XML报文的总长度或者为负数,如果当前位置的值超过了其所属XML报文的总长度或为负数,返回错误,否则,执行步骤103;
步骤103,判断当前位置对应的字符是否为“<”或“>”,如果是,执行步骤105,如果不是,执行步骤104;
步骤104,将当前位置移动一个单位,将移动一个单位后得到的字符作为当前位置,执行步骤102;
其中,在本实施例中,移动一个单位具体的为移动一个字符的长度;
在本步骤中,将当前位置移动移动一个单位可以向前移动,也可以向后移动,因此,步骤104具体的可以为:
将当前位置向前移动一个单位,将向前移动一个单位后得到的字符作为当前位置,并将表示当前位置的值递减1,执行步骤102,
或,
将当前位置向后移动一个单位,将向后移动一个单位后得到的字符作为当前位置,并将表示当前位置的值递增1,执行步骤102,
步骤105,将当前位置作为当前节点的节点边界,并将当前位置移动一个单位,将移动一个单位后得到的字符的位置设置为当前位置;
在本实施例中,节点边界包括节点头和节点尾;
因此,当步骤105中,将当前位置作为当前节点的节点头时,步骤105具体的为:将当前位置记录为当前节点的节点头a1,并将当前位置向后移动一个单位,即令A=a1+1,将移动一个单位后得到的字符的位置设置为当前位置;
例如,在本实施例中,设当前位置A=0,则当前位置的字符为“<”,将当前位置A=0作为节点的节点头,令a1=0,并且将当前位置向后移动一个单位,使得当前位置为A=1;
当步骤105中,将当前位置作为当前节点的节点尾时,步骤105具体的为:将当前位置记录为当前节点的节点尾a2,并将当前位置向前移动一个单位,即令A=a2-1,将向前移动一个单位后得到的字符的位置设置为当前位置;
在本发明中,当前位置、当前节点同当前元素一样,表示XML解析器正在处理的对象,不固定为某一具体对象,当前位置、当前节点所指代的对象由上一步骤指示得到,相应的,用于表示当前位置的值A,也为相同情况,随着当前位置的改变而改变。
步骤106,判断当前位置的值是否超过XML报文的总长度或者为负数,如果当前位置的值超过了其所属XML报文的总长度或为负数,返回错误,否则,执行步骤107;
在本实施例中,执行到此步骤时,当前位置的值为1,不为负数且不超过XML报文的总长度,则执行步骤107;
步骤107,判断当前位置对应的字符是否为“<”或“>”,如果是,执行步骤108,如果不是,将当前位置按与步骤105中当前位置移动方向相同的方向移动一个单位,将移动一个单位后得到的字符的位置作为当前位置,返回执行步骤106;
具体地,在本实施例中,当步骤105中,将当前位置记录为当前节点的节点头a1,并将当前位置向后移动一个单位时,步骤107具体的为:
判断当前位置对应的字符是否为“<”或“>”,如果是,执行步骤108,如果不是,将当前位置向后移动一个单位,将向后移动一个单位后得到的字符的位置作为当前位置,并将当前位置的值递增1,返回执行步骤106;
例如在本实施例中,当前位置A=1时,对应的字符为“?”,不是“<”或“>”,因此需要将当前位置向后移动一个单位,即令当前位置A=2,并返回执行步骤106;
当步骤105中,将当前位置作为当前节点的节点尾时,步骤105具体的为:将当前位置记录为当前节点的节点尾a2时,步骤107具体的为:
判断当前位置对应的字符是否为“<”或“>”,如果是,执行步骤108,如果不是,将当前位置向前移动一个单位,将向前移动一个单位后得到的字符的位置作为当前位置,并将当前位置的值递减1,返回执行步骤106;
步骤108,将当前位置作为当前节点的另一个节点边界,得到当前节点。
具体地,当步骤105中,将当前位置记录为当前节点的节点头a1,并将当前位置向后移动一个单位时,步骤108具体的为:
将当前位置作为当前节点的节点尾a2,得到当前节点(a1,a2)。
当步骤105中,将当前位置作为当前节点的节点尾时,步骤105具体的为:将当前位置记录为当前节点的节点尾a2时,步骤108具体的为:
将当前位置作为当前节点的节点头a1,得到当前节点(a1,a2)。
其中,由于步骤101中以当前位置A=0开始对节点进行划分为例进行说明,在步骤107中,由于当前位置不是字符“<”或“>”,因此将当前位置向后移动一个单位,再返回执行步骤106,只要当前位置的字符不为“<”或“>”,则将当前位置以一个字符为单位一直后移,并且每次后移后,判断当前位置是否为“<”或“>”,在本实施例中,当当前位置A=39时,得到字符“>”,判断得到为当前节点的节点尾,因此上述XML报文的第一个节点使用二元组表示为(0,39),节点长度为40,当前节点具体的为:
“<?xml version=″1.0″encoding=″utf-8″?>”
通过上述方法,可以由XML报文的任意位置开始将XML报文进行节点的划分,本实施例中所提供的节点划分方法,使用数组表示一个节点,数组中为节点的节点头和节点尾的偏移,在使用上述节点划分方法进行XML报文的解析时,不需要将全部节点的字符读入内存,可以节省内存空间,尤其适用于嵌入式环境中或在内存较小的智能密钥设备中应用。
实施例2
基于实施例1所提供的一种节点划分方法,本实施例提供了一种XML报文中节点类型的判断方法,参加图3,具体的如下:
步骤201,判断当前节点是否为以“<”开头,以“>”结尾,如果是,则执行步骤202,如果不是,执行步骤207;
在本步骤中,划分得到下一个节点的方法与实施例1中相同,这里不再赘述;
步骤202,判断当前节点中字符“<”之后的第一个位置对应的字符,如果为“?”,执行步骤203,如果为“!”,执行步骤204,如果为“/”,执行步骤205,否则,执行步骤206;
步骤203,判断当前节点中字符“>”之前的位置所对应的字符是否为“?”;
如果是,判断“<”之后的下一个位置的“?”与“>”之前第一个位置的“?”是否重合,如果不重合,则记录所述节点为XML报文的头,如果重合,报错;
例如在本实施例中,节点头为<?xml version=″1.0″encoding=″utf-8″?>,即为以“<”开头,以“>”结尾的节点,并且当前节点中字符“<”之后的第一个“?”与由字符“>”向前读取出现的第一个“?”的位置不重合;
如果不是,则报错,当前报文有误;
步骤204,记录当前节点为不需要解析的部分;
需要说明的是,在本实施例中,以“<!--”开头的节点为XML报文注释,以“<!DOCTYPE”开头的节点为报文类型定义,以“<![CDATA”开头的节点为无需解析的文本;
步骤205,记录当前节点为元素尾;
其中,在XML报文中,以“</”开头的节点为元素的元素尾;
步骤206,判断当前节点中字符“>”前的一个字符是否为“/”,如果是,则记录当前节点为一个完整的元素,否则,记录当前节点为一个元素的元素头。
其中,在XML报文中,元素的名称包含在元素头和元素尾的节点中,在元素尾的节点中,元素的名称是“</”和“>”之间的字符串,例如在上述XML报文中,节点“</Timestamp>”为元素尾,“Timestamp”为元素名称;在元素头节点中,元素的名称是“<”到第一个空格之间的字符串,如果没有空格,就是“<”和“>”之间的字符串;
步骤207,判断当前节点是否以“>”开头,以“<”结尾,如果是,则记录当前节点为元素中间的值,如果不是,返回错误,停止对节点类型的判断。
其中,在XML报文中,一个节点应以“<”开头,以“>”结尾,或以“>”开头,以“<”结尾。
本实施例提供了一种基于实施例1所提供的节点划分方法的节点类型判断方法,根据所述节点类型判断方法可以对划分得到的任何节点的类型进行判断,并记录节点类型。
实施例3
基于实施例1所提供的一种节点划分方法,本实施例提供了一种XML报文中定位元素的方法,所述定位元素的方法可以由任意节点定位其所属的元素,参加图4,具体的为:
在本实施例中,为了便于说明,设一个任意节点为当前节点N1,并且设节点N1所属的元素为M,元素M使用一个二元组表示,二元组中分别为元素M的元素头和元素尾;
步骤301,判断当前节点的类型,如果是完整元素,执行步骤302,如果是元素头,执行步骤303,如果是元素尾,执行步骤305,如果是元素中间的值,执行步骤307,如果是不需要解析的部分,执行步骤308,如果是报文头,返回错误;
其中,判断节点类型的方法为实施例2所提供的方法,这里不再赘述;
并且,在本实施例中,元素中间的值,指的是一个元素中,元素头和元素尾中间的值,例如在元素“<Timestamp>12345</Timestamp>”中,12345即为元素之间的值;
步骤302,记录当前节点N1所属元素为M(N1,N1);
步骤303,根据实施例1所提供的节点划分方法,对XML报文中当前节点N1后的字符划分得到下一个节点,将所述下一个节点定义为节点N2;
步骤304,根据实施例2所提供的节点类型判断方法,判断节点N2的类型:
如果是元素尾,则判断节点N2中的元素名称与节点N1中的元素名称是否相同,如果相同,则得到当前所属元素为(N1,N2),如果不相同,根据实施例1所提供的节点划分方法,继续对XML报文中节点N2后的下一个节点进行划分,并将所述节点N2后的下一个节点设为新的节点N2,返回步骤304,继续判断节点N2的类型;
如果是元素头,则判断节点N2中的元素名称与节点N1中的元素名称是否相同,如果相同,返回错误,如果不相同,根据实施例1所提供的节点划分方法,继续对XML报文中节点N2后的下一个节点进行划分,并将所述节点N2后的下一个节点设为新的节点N2,返回步骤304,继续判断节点N2的类型;
如果是元素中间的值,根据实施例1所提供的节点划分方法,继续对XML报文中节点N2后的下一个节点进行划分,并将所述节点N2后的下一个节点设为新的节点N2,返回步骤304,继续判断节点N2的类型;
步骤305,根据实施例1所提供的节点划分方法,对XML报文中当前节点N1前的字符划分得到上一个节点,将所述上一个节点定义为节点N3;
步骤306,根据实施例2所提供的节点类型判断方法,判断节点N3的类型:
如果是元素头,判断节点N3中的元素名称与节点N1中的元素名称是否相同,如果相同,则得到当前所属元素为(N3,N1),如果不相同,根据实施例1所提供的节点划分方法,继续对XML报文中节点N3的前一个节点进行划分,并将所述节点N3的前一个节点设为新的节点N3,返回步骤306,继续判断节点N3的类型;
如果是元素尾,判断节点N3中的元素名称与节点N1中的元素名称是否相同,如果相同,返回错误,如果不相同,根据预先约定的节点划分方法,继续对XML报文中节点N3的前一个节点进行划分,并将所述节点N3的前一个节点设为新的节点N3,返回步骤306,继续判断节点N3的类型;
如果是元素中间的值,根据实施例1所提供的节点划分方法,继续对XML报文中节点N3的前一个节点进行划分,并将所述节点N3的前一个节点设为新的节点N3,返回步骤306,继续判断节点N3的类型;
步骤307,根据实施例1所提供的节点划分方法,对XML报文中节点N1的前一个节点N4和后一个节点N5进行划分,并判断节点N4和N5的类型:
如果节点N4和N5都是元素头,则节点N4和N1同属一个元素,按照方法一找到节点N4和N1所属元素的元素尾N6,得到当前节点所属的元素(N4,N6);
如果节点N4和N5都是元素尾,则节点N5和N1同属一个元素,按照方法二找到节点N5和N1所属元素的元素头N7,得到当前节点所属的元素为(N7,N5);
如果节点N4为元素头,节点N5为元素尾,则继续判断节点N4中所包含的元素名称与节点N5中所包含的节点名称是否相同,如果相同,得到当前节点所属的元素为(N4,N5),如果不相同,返回错误;
如果节点N5为元素头,节点N4为元素尾,返回错误;
本步骤中,所述方法一和方法二具体的为:
方法一:
a,根据实施例1所提供的节点划分方法,划分得到节点N5的下一个节点,并设为临时节点N6;
b,根据实施例2所提供的节点类型判断方法,判断临时节点N6是否为元素尾,如果是,执行步骤c,如果不是,根据实施例1所提供的节点划分方法,继续划分得到临时节点N6的下一个节点,并设为临时节点N6,返回重新执行步骤b;
c,判断临时节点N6中的元素名称与节点N4中的元素名称是否相同,如果相同,则将临时节点N6置为节点N6,如果不相同,则根据实施例1所提供的节点划分方法,继续划分得到临时节点N6的下一个节点,并设为临时节点N6,返回重新执行步骤b;
方法二:
a’,根据实施例1所提供的节点划分方法,划分得到节点N4的上一个节点,并设为临时节点N7;
b’,根据实施例2所提供的节点类型判断方法,判断临时节点N7是否为元素头,如果是,执行步骤c’,如果不是,根据实施例1所提供的节点划分方法,继续划分得到临时节点N7的上一个节点,并设为临时节点N7,返回重新执行步骤b’;
c’,判断临时节点N7中的元素名称与节点N5中的元素名称是否相同,如果相同,则将临时节点N7置为节点N7,如果不相同,则根据实施例1所提供的节点划分方法,继续划分得到临时节点N7的上一个节点,并设为临时节点N7,返回重新执行步骤b’;
步骤308,对XML报文中节点N1的下一个节点进行划分并设为新的节点N1,判断节点N1是否为需要解析的部分,如果是,返回步骤301,如果不是需要解析的部分,重新执行本步骤操作,继续划分得到下一个节点,并判断所述下一个节点是否为需要解析的部分,直到节点位置超出XML报文的总长;
在本实施例中,步骤308还可以按照如下方式实现:
步骤308’,对XML报文中节点N1的前一个节点进行划分并设为新的节点N1,判断节点N1是否为需要解析的部分,如果是,返回步骤301,如果不是需要解析的部分,重新执行本步骤操作,继续划分得到前一个节点,并判断所述前一个节点是否为需要解析的部分,直到表示节点位置的值为负数;
上述步骤301到步骤308描述的为由任意节点作为当前节点,定位其所属元素的方法,由本实施例所提供的方法,还可以定位根元素:
1)将XML报文中的第一个节点设为节点S1,根据实施例2所提供的节点判断方法,判断S1是否为根元素的元素头,如果是,执行步骤2),如果不是,划分得到节点S1的下一个节点并设为节点S1,继续判断节点S1是否为根元素的元素头;
2)根据实施例1提供的节点划分方法,划分得到节点S1的下一个节点,设为节点S2,判断节点S2的名称与根元素的元素名称是否相同,如果相同,则根元素为(S1,S2),如果不相同,划分得到节点S2的下一个节点并设为节点S2,继续判断节点S2的名称是否与根元素的元素名称相同,直到节点位置超出XML报文的总长。
实施例4
基于实施例1所提供的一种节点划分方法,本实施例提供了一种XML报文中定位当前元素的第一个子元素的方法,参见图5,具体的如下:
在本实施例中,为了便于说明,设当前元素为M=(A1,A2),其中,M表示当前元素,节点A1为当前元素的元素头,节点A2为当前元素的元素尾,并且A1=(a11,a12),A2=(a21,a22),a11为表示节点A1的节点头位置的值,a12为表示节点A1的节点尾位置的值,a21为表示节点A2的节点头的位置的值,a22为表示节点A2的节点尾的位置的值;
步骤401,从当前元素的元素头的节点尾开始,划分得到当前元素的元素头的节点的下一个节点,设为A3;
步骤402,判断节点A3的位置是否超出了当前元素的元素尾,如果是,返回错误,如果不是,执行步骤403;
步骤403,判断节点A3的类型:
如果是元素头且名称与当前元素M的名称不同,执行步骤404;;
如果是元素尾,执行步骤406;
否则,执行步骤407;
步骤404,记录A3为当前元素的第一个子元素的元素头;
步骤405,根据实施例2中所提供的元素定位方法,由节点A3定位当前元素的第一个子元素;
在本步骤中,由当前元素的第一个子元素的元素头进行定位,定位方法与实施例2中由任意节点定位其所属元素的方法相同,这里不再赘述,需要说明的是,在定位当前元素M的第一个子元素,即节点A3所属元素的过程中,由节点A3向后划分节点时,不能超过位置a12,如果超过位置a12,则报错;
步骤406,判断所述当前元素的下一个节点与当前元素的元素尾是否重合,即节点A3与A2是否重合,如果是,当前元素没有子元素,如果不是,返回报文错误;
步骤407,继续划分得到节点A3的下一个节点,并将得到的节点A3的下一个节点设为新的节点A3,返回步骤402;
本实施例提供了一种定位当前节点的第一个子元素的方法,在XML报文的解析过程中,可以定位任一个元素的第一个子元素。
实施例5
基于实施例1所提供的一种节点划分方法,本实施例提供了一种XML报文中相邻元素的定位方法,参见图6,具体的如下:
在本实施例中,所述相邻元素的定位方法可以由任意元素定位其相邻元素,为了便于说明,将当前元素设为A=(A4,A5),其中A为当前元素,A4为当前元素A的元素头,A5为当前元素的元素尾,并且A4=(a41,a42),A5=(a51,a52),a41为表示节点A4的节点头位置的值,a42为表示节点A4的节点尾位置的值,a51为表示节点A5的节点头的位置的值,a52为表示节点A5的节点尾的位置的值;
步骤501,判断当前元素A是否为根元素,如果是,当前元素没有相邻元素,如果不是,执行步骤502;
步骤502,查找当前元素A的父元素,并根据预先约定的父元素的定位方法,定位当前元素的父元素的位置;
具体的,在本发明中,预先约定的父元素的定位方法可以对任意元素查找当前元素的父元素,具体的方法为:
同上,设当前元素为A=(A4,A5),A4=(a41,a42),A5=(a51,a52);
502-1,判断当前元素A是否为根元素,如果是,则当前元素没有父元素,如果不是,执行步骤502-2;
在本实施例中,判断根元素的方法具体的可以为:在对XML进行解析时,由报文起始点开始,查找第一个节点,判断第一个节点的类型,如果是报文头,则继续向后查找节点并判断节点类型,找到出现的第一个元素头,则该元素头为根元素的元素头,根据该元素头定位根元素,并记录,以此判断当前元素是否为根元素;
502-2,根据预先约定的节点划分方法,查找并划分当前元素A的元素头的上一个节点,并设为A6;
502-3,根据预先约定的节点类型判断方法,判断节点A6的类型,如果为元素头,执行步骤502-4,如果不是元素头,执行步骤502-5;
502-4,节点A6为当前元素A的父元素的元素头,根据预先约定的元素定位方法,由节点A6定位得到当前元素A的父元素P=(A6,A7),并且A6=(a61,a62),A7=(a71,a72),a61为元素头A6的节点头,a62为元素头A6的节点尾,a71为元素尾A7的节点头,a72为元素尾A7的节点尾;
502-5,根据预先约定的节点划分方法,查找并划分节点A6的上一个节点,并将所述节点A6的上一个节点设为新的节点A6,返回步骤502-3。
步骤503,根据所述预先约定的节点划分方法,从当前元素A的元素尾即a52向后划分得到下一个节点,并设为节点A8,
步骤504,判断节点A8是否超出当前元素A的父元素的范围(即判断A8是否超出了当前元素A的父元素P的元素尾a71):
如果是,执行步骤505;
如果不是,执行步骤506;
步骤505,停止对当前元素的相邻元素的查找;
步骤506,判断节点A8的类型是否为元素头,如果是元素头,则A8为当前元素A的相邻元素的元素头,由节点A8定位当前元素A的相邻元素,否则,划分得到节点A8的下一个节点,并设为新的节点A8,返回步骤504。
在本实施例中,步骤503和504,采取XML报文从上到下的,从左到右的解析方法,还可以采取由当前节点同时向两边的查找相邻元素的方法,此时,步骤503至506可以替换为:
从当前元素A的元素头即a41向前逐个划分节点,并判断所述从当前元素的元素头向前划分的节点类型,如果是元素尾,则为相邻元素的元素尾,根据元素尾定位相邻元素,否则,继续向前进行节点的划分,直到划分到当前元素A的父元素P的元素头即a62之后;并且,从当前元素A的元素尾即a52开始向后逐个划分节点,并判断所述从当前元素A的元素头向后划分的节点类型,如果是元素头,则为当前元素的相邻元素的元素头,根据所述元素头定位相邻元素,否则,继续向后进行节点的划分,直到划分到当前元素A的父元素P的元素尾即a71之前。
实施例6
基于实施例1-5所提供的一种对XML报文中的节点进行划分的方法及基于上述节点划分方法的节点类型判断方法、定位元素方法、定位当前元素的第一个子元素的方法、相邻元素的定位方法,本实施例提供了一种XML报文的解析方法,具体的如下:
步骤601,获取XML报文的根元素,将所述根元素设为当前元素;
其中,获取XML报文根元素的方法与实施例3中所述相同,这里不再赘述;
步骤602,判断当前元素是否有子元素,如果有,执行步骤603,如果没有,执行步骤605;
步骤603,查找当前元素的第一个子元素;
在本步骤中,查找当前元素的第一个子元素使用实施例4所提供的定位当前元素的第一个子元素的方法,这里不再赘述;
步骤604,将步骤603中获得的第一个子元素置为当前元素,并返回步骤602;
步骤605,判断当前元素之后是否有相邻元素,如果有,执行步骤606,如果没有,执行步骤608;
步骤606,定位并获取当前元素的相邻元素;
在本步骤中,定位并获取当前元素的相邻元素使用实施例5所提供的相邻元素的定位方法,这里不再赘述;
步骤607,将上述相邻元素置为当前元素,返回步骤602;
步骤608,将当前元素的父元素作为当前元素,并判断当前元素是否为根元素,如果是,执行步骤609,如果不是,并返回步骤605;
在本步骤中,查找当前元素的父元素的方法与实施例5中查找当前元素的父元素的方法相同,这里不再赘述;
步骤609,XML报文解析完成。
在本实施例中,在对元素进行定位的过程中,还包括对当前元素的名称的判断,如果解析器发现XML报文中所需的元素已经完成解析并获得得到了相应元素的数据,则停止XML报文的解析,以节省内存。
本实施例所提供的一种XML报文的解析方法,无需在内存中建立完整的节点树,内存使用小,适合内存小的装置进行XML报文的解析,并且本实施例所提供的方法,适合C语言进行实现,因此可以支持嵌入式环境的应用。
在实施例1-6中,元素A、A1、A2、A3、A4、A5、A6、A7、A8、节点N、N1、N2、N3、N4、N5、N6、N7、N8、N9以及各临时节点,都同当前元素的表示方法,为不固定的指定为XML报文中某个对象,而且根据XML上一步骤或本步骤中的指示而指代的对象,这在本领域技术人员中,应该是可以理解的。
以上实施例分别一种对XML报文中的节点进行划分的方法及基于上述节点划分方法的节点类型判断方法、定位元素方法、定位当前元素的第一个子元素的方法、相邻元素的定位方法、XML报文的解析方法进行了详细介绍,本文中应用了具体个例对本发明的原理及实施方式进行了阐述,以上实施例的说明只是用于帮助理解本发明的方法及其核心思想;同时,对于本领域的一般技术人员,依据本发明的思想,在具体实施方式及应用范围上均会有改变之处,综上,本说明书内容不应理解为对本发明的限制。
以上仅为本发明的较佳实施例,并不用以限制本发明,凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。