数据转换方法、装置、电子设备及可读存储介质与流程

专利2022-05-10  38



1.本技术涉及数据处理技术领域,具体而言,涉及一种数据转换方法、装置、电子设备及可读存储介质。


背景技术:

2.通常通讯双方可按照约定的数据格式(例如协议)进行数据交互,例如通过json(java script object notation)数据进行交互,json数据是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。但是即便如此,通讯双方仍面临着有在不同数据结构的json数据之间交换数据的需求,所以,往往需要将数据转换为所需求的数据结构。目前通常做法是技术人员进行人工转换,这种方式效率低,且耗时较长。


技术实现要素:

3.本技术实施例的目的在于提供一种数据转换方法、装置、电子设备及可读存储介质,用以改善现有技术中人工转换效率低、耗时长的问题。
4.第一方面,本技术实施例提供了一种数据转换方法,所述方法包括:
5.获取第一类数据与第二类数据之间的转换映射关系,所述转换映射关系是指所述第一类数据对应的第一字段向量集合中的多个第一字段向量与所述第二类数据对应的第二字段向量集合中的多个第二字段向量之间的映射关系,其中,所述多个第一字段向量是指与所述第一类数据中的字段具有对应关系的向量,所述第一字段向量中的不同元素用于表征其所对应字段的不同字段特征;所述多个第二字段向量是指与所述第二类数据中的字段具有对应关系的向量,所述第二字段向量中的不同元素用于表征其所对应字段的不同字段特征;所述字段特征包括字段的层级、名称、类型、父节点中的至少两个;
6.获取源数据,所述源数据属于所述第一类数据;
7.根据所述转换映射关系,对所述源数据进行转换,得到目标数据,所述目标数据属于所述第二类数据。
8.第二方面,本技术实施例提供了一种数据转换装置,所述装置包括:
9.映射关系获取模块,用于获取第一类数据与第二类数据之间的转换映射关系,所述转换映射关系是指所述第一类数据对应的第一字段向量集合中的多个第一字段向量与所述第二类数据对应的第二字段向量集合中的多个第二字段向量之间的映射关系,其中,所述多个第一字段向量是指与所述第一类数据中的字段具有对应关系的向量,所述第一字段向量中的不同元素用于表征其所对应字段的不同字段特征;所述多个第二字段向量是指与所述第二类数据中的字段具有对应关系的向量,所述第二字段向量中的不同元素用于表征其所对应字段的不同字段特征;所述字段特征包括字段的层级、名称、类型、父节点中的至少两个;
10.数据获取模块,用于获取源数据,所述源数据属于所述第一类数据;
11.转换模块,用于根据所述转换映射关系,对所述源数据进行转换,得到目标数据,
所述目标数据属于所述第二类数据。
12.第三方面,本技术实施例提供一种电子设备,包括处理器以及存储器,所述存储器存储有计算机可读取指令,当所述计算机可读取指令由所述处理器执行时,运行如上述第一方面提供的所述方法中的步骤。
13.第四方面,本技术实施例提供一种可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时运行如上述第一方面提供的所述方法中的步骤。
14.本技术的其他特征和优点将在随后的说明书阐述,并且,部分地从说明书中变得显而易见,或者通过实施本技术实施例了解。本技术的目的和其他优点可通过在所写的说明书、权利要求书、以及附图中所特别指出的结构来实现和获得。
附图说明
15.为了更清楚地说明本技术实施例的技术方案,下面将对本技术实施例中所需要使用的附图作简单地介绍,应当理解,以下附图仅示出了本技术的某些实施例,因此不应被看作是对范围的限定,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他相关的附图。
16.图1为本技术实施例提供的一种数据转换方法的流程图;
17.图2为本技术实施例提供的一种映射关系的示意图;
18.图3为本技术实施例提供的一种数据转换装置的结构框图;
19.图4为本技术实施例提供的一种用于执行数据转换方法的电子设备的结构示意图。
具体实施方式
20.下面将结合本技术实施例中附图,对本技术实施例中的技术方案进行清楚、完整地描述。
21.本技术实施例提供一种数据转换方法,该方法获取第一类数据和第二类数据之间的转换映射关系,并根据转换映射关系将属于第一类数据的源数据转换为属于第二类数据的目标数据,如此可自动实现数据转换,从而可避免人工转换导致的耗时长、效率低的问题。
22.请参照图1,图1为本技术实施例提供的一种数据转换方法的流程图,该方法包括如下步骤:
23.步骤s110:获取第一类数据与第二类数据之间的转换映射关系。
24.本技术实施例中所说的第一类数据和第二类数据均可以为json数据,二者具有不同的数据结构,第一类数据可以理解为是一种数据结构的json数据,第二类数据可以理解为是另一种数据结构的json数据。为了能够正确处理不同类型的json数据,需要在不同数据结构的json数据之间进行转换。例如,通信发起者以第一数据结构将json数据传输到接收者,但接收者却以第二数据结构接收json数据。
25.在进行转换时,可以预先存储有两类数据之间的转换映射关系,即第一类数据与第二类数据之间的转换映射关系,从而可以根据转换映射关系来进行数据转换。或者,若是第一类数据与第二类数据之间的转换映射关系是会发生变化的,则也可以在确定了需要在
其之间转换的两类数据后,实时获得转换映射关系。
26.转换映射关系可以是指第一类数据对应的第一字段向量集合中的多个第一字段向量与第二类数据对应的第二字段向量集合中的多个第二字段向量之间的映射关系。其中,多个第一字段向量是指与第一类数据中的字段具有对应关系的向量,第一字段向量中的不同元素用于表征其所对应字段的不同字段特征;多个第二字段向量是指与第二类数据中的字段具有对应关系的向量,第二字段向量中的不同元素用于表征其所对应字段的不同字段特征,所述字段特征包括字段的层级、名称、类型、父节点中的至少两个。
27.其中,字段向量与字段的对应关系可以是一个字段对应一个字段向量,即二者一一对应。
28.其中,json数据的字段具有字符串(string)、布尔值(bool)、实数(number)、数组(array)、对象(object)等5种类型。如表1所示,字段key1是字符串类型的数据,取值为“字符串”;字段key2是布尔值类型,取值为true;key3是实数类型,取值10;key4是数组类型,具有3个元素,元素类型都是实数;key5是对象类型,该对象具有一个实数类型的字段key6,取值为9。很明显,“example”本身也是一个对象,具有key1~key5共5个字段。
29.表1
[0030][0031][0032]
上述表1所示的json数据可以理解为是其中一种数据结构的数据,如可以认为是第一类数据,在获得第一类数据后,可提取第一类数据对应的第一字段向量集合,提取的方式如下:
[0033]
可以用一个自然数代表字段在数据中所处的json层级,简称层级,如上述表1中从第一个左花括号“{”开始,代表层级为1,以后每次遇到一个左花括号“{”,层级就加1,而遇到一个右花括号“}”,层级就减1。例如,上述example字段的层级为1,key1的层级为2,key6的层级为3。
[0034]
如果某个字段s属于一个对象类型的字段,就称s的父节点就是这个对象类型的字段,对于层级为1的字段,称其父节点为根节点,对于数组则有例外,数组元素的父节点是数组(数据元素如果为对象类型,则此元素的父节点都是该数组),例如,上述表1中的key1的父节点是example,元素1、2、3的父节点是key4。
[0035]
所以,对于数据中的任意字段都能用不同的字段特征形成的向量来表示,如
{level,name,type,parent}(层级、名称、类型、父节点)4个维度的向量唯一进行确定,也就是说,每个字段都能映射为这种形式的字段向量,这样就可以获得第一类数据对应的第一字段向量集合。例如,对于上述表1中的json数据,各个字段对应的第一字段向量如下:
[0036]
x1=example={1,example,object,root};
[0037]
x2=key1={2,key1,string,example};
[0038]
x3=key2={2,key2,bool,example};
[0039]
x4=key3={2,key3,number,example};
[0040]
x5=key4={2,key4,array,example,number};
[0041]
x6=key5={2,key5,object,example};
[0042]
x7=key6={3,key6,number,key5}。
[0043]
上述x1,x2,...,x7向量即形成了第一字段向量集合,第一字段向量集合即可表征该json数据(即第一类数据)的数据结构,所以,可以根据这7个向量生成形如该数据结构的第一类数据。为了便于描述,可以用x=[x1,x2,x3,x4,x5,x6,x7]代表该第一类数据对应的第一字段向量集合。
[0044]
需要说明的是,上述中使用三个维度:level、name、parent(层级和层次关系)就可以确定字段在数据中的位置关系了,引入type是为了在数据转换时有更多的选择,例如判断数据类型不同时进行报错,或尝试进行数据转换。而针对数组类型的字段,可以新增第5个维度(subtype)用于表示数组元素的类型,例如当该维度为字符串类型string时,代表数组的元素全部是字符串;当该维度为对象类型object时,代表数组的元素全部是对象;当该维度默认为空,表示数组的元素可以取任意类型的json数据。本实施例中只考虑以下数组(限制条件):(1)数组元素类型全部相同的情况(bool、string、number、object 4种,不含array);(2)数组元素类型全为array,但是数组的每个元素(也是数组)不能包含object,也就是说类似于这种[[{obj1},{obj2},...,{objn}]]结构复杂且很罕见,不予考虑;(3)数组元素类型都是值类型(bool、string、number),值类型指除了object或array以外的类型。
[0045]
可以理解的是,在一个源数据或目标数据中,可能出现两个字段向量完全相同的字段。例如下例中数组类型的字段"a1"所包含的两个数组元素中,都包含"key1"字段,二者字段向量相同,只是字段值不同。
[0046][0047]
[0048]
下面举例说明如何进行数据转换。如表2所示,右侧的数据是对左侧的json数据进行转换后的数据,表2右侧部分所示的数据可以认为是第二类数据。其中,key1,...,key6名称变为item1,...,item6;key1、key5的层级由2变为1,相应的父节点变为根节点;example名称变为test;同时原本属于example的字段key2,跑到key5下面了,可见两类数据的数据结构不同。
[0049]
表2
[0050][0051]
按照上述获得第一类数据对应的第一字段向量集合的方式,同样也可以获得第二类数据对应的第二字段向量集合,如左侧的json数据对应的第一字段向量集合为src=x=[x1,x2,x3,x4,x5,x6,x7],右侧的json数据对应的第二字段向量集合为dst=x’=[x1’,x2’,x3’,x4’,x5’,x6’,x7’]。所以,这样就可以根据两个字段向量集合中各个字段向量中的元素信息之间的关联,获得各个第一字段向量与第二字段向量之间的映射关系。如x1

>x2’,x2

>x1’,从而即可完成转换工作。
[0052]
步骤s120:获取源数据,所述源数据属于所述第一类数据。
[0053]
源数据可以是指需要转换为第二类数据的数据,源数据是属于上述第一类数据的数据,其具有第一类数据的数据结构,即源数据中各个字段的名称、类型、层级和父节点与第一类数据中的各个字段相同。
[0054]
步骤s130:根据所述转换映射关系,对所述源数据进行转换,得到目标数据,所述目标数据属于所述第二类数据。
[0055]
获得了第一类数据和第二类数据之间的转换映射关系,也就获得了第一字段向量集合与第二字段向量集合的转换映射关系,从而可根据转换映射关系将源数据中符合第一字段向量所描述的字段特征的字段转换为符合第二字段向量所描述特征的字段,这些字段构成了转换后的目标数据。
[0056]
在上述实现过程中,可自动实现数据转换,从而可避免人工转换导致的耗时长、效率低的问题。且还可避免人工转换导致的错误率高的问题。
[0057]
在上述实施例的基础上,假设转换映射关系定义为映射函数dst=f(src),则根据
该映射函数,就能将表2中左侧的json数据转换为右侧的json数据;而且,如果f是满射(如图2所示),则还能将右侧的json数据通过f的逆函数,转换回左侧的json数据;再者,如果对于3个json结构x、x’、x”,x和x’,x和x”之间具有满射关系,那么x’和x”也具有满射关系,在任意两个json数据之间也可以互相转换。
[0058]
在获得转换映射关系的过程中,可以事先获得第一类数据对应的第一字段向量集合,如记作x=[x1,x1,...,xn];事先获得第二类数据对应的第二字段向量集合,记作y=[y1,y2,...,ym]。然后可将这两类数据对应的字段向量集合保存到文件(或数据库,或其他存储设备/软件/系统),其中,可以分别保存为不同的文件,也可以保存到同一个文件。
[0059]
然后可构造第一字段向量集合到第二字段向量集合之间的映射函数f,其中y=f(x),f可以是一个<k,v>的映射表(即map)。为了确保映射不会错乱,本实施例中,只考虑f为单射的情况,即一个字段向量只会被映射为另一个字段向量,不会出现两个字段向量被映射为同一个字段向量的情况。
[0060]
其中,f是一个映射表,如给定某个变量x,可以得到所对应的y。x,y可以是字段向量的索引,例如取字段向量的编号1,2,3...,或字段向量的名称,只要可以唯一表示字段向量即可。然后可将该映射表f保存到文件(或数据库,或其他存储设备/软件/系统),可以单独保存成文件,也可以和字段向量保存在同一个文件。
[0061]
在获得映射表f后,对于从属于第一类数据的源数据转换为属于第二类数据的目标数据,可以遍历源数据中各字段,针对遍历到的字段key,到映射表f获取key对应的字段向量x0所映射的字段向量y0=f(x0),根据key的类型、取值,以及y0构造目标数据中的目标字段key’。若f为满射,则通过遍历源数据中各字段可以构造出目标数据中的所有字段;若f为非满射,则目标数据的某些字段未能通过遍历源数据中的字段被构建。
[0062]
其中,若映射表f中没有关于字段向量x0的映射关系,说明构建目标数据时无需使用key,此时将字段key忽略。这在某些情况下有用,比如需要从一个大的json数据里提取少数关键字段,另一些字段则不使用。
[0063]
对于从属于第二类数据的源数据转换为属于第一类数据的目标数据,可以把映射表<x,y>的键值对互相调换即可,变为<y,x>,这时json数据转换方法同上述的方法一样。
[0064]
在上述实施例的基础上,本技术另一实施例中,步骤s130包括:
[0065]
步骤s131:获取初始化的目标数据。
[0066]
其中,初始化的目标数据是指构建一个初始化为空的数据,只包含有根节点,即“{}”。
[0067]
步骤s132:进行目标字段构建。
[0068]
目标字段构建的过程如下:
[0069]
s1:从源数据中确定当前源字段。
[0070]
优选的,为提高遍历效率,从源数据中未作为过当前字段的字段中确定当前源字段。
[0071]
s2:从第二字段向量集合中确定当前第二字段向量;
[0072]
其中,当前源字段对应的当前第一字段向量和当前第二字段向量之间具有映射关系。
[0073]
可以理解的是,步骤s1和步骤s2可以以任意顺序先后执行,可先执行s1再执行s2
或先执行s2再执行s1。先执行s1时,是从源数据的维度或第一字段向量的进行遍历,先执行s2时,是从第二字段向量的维度进行遍历。无论从哪个维度进行遍历,都需要在各次执行步骤s132时均通过相同的方式遍历,否则将无法判定遍历是否已完成。
[0074]
由于当前源字段对应的当前第一字段向量和当前第二字段向量之间具有映射关系,确认了当前源字段或当前第二字段向量中的一者后,即可根据映射关系确认另一者。例如,可以先从源数据中未作为过当前字段的字段中确定当前源字段,再将与当前源字段对应的当前第一字段向量具有映射关系的第二字段向量作为当前第二字段向量。或者,先从第二字段向量集合中未作为过当前第二字段向量的向量中确定当前第二字段向量,再将与当前第二字段向量具有映射关系的第一字段向量对应的源字段作为当前源字段。
[0075]
需要说明的是,如果先执行s2再执行s1(即从第二字段向量的维度进行遍历),在执行s2时,可以从第二字段向量集合中未作为过当前第二字段向量的向量中确定当前第二字段向量,以避免重复遍历已经遍历过的内容(作为过当前第二字段向量的第二字段向量),从而尽快完成遍历。
[0076]
s3:根据所述当前第二字段向量和/或所述当前源字段,在目标数据中构建所述当前第二字段向量对应的当前目标字段。
[0077]
在目标数据中构建所述当前第二字段向量对应的当前目标字段,即为在目标数据中满足第二字段向量描述的位置处构建当前目标字段,并使当前目标字段的值满足第二字段向量描述的类型。
[0078]
可以理解的是,循环执行步骤s132的过程就是进行遍历的过程,遍历时可采用多种手段,例如按字段在源数据中的次序遍历,按字段或字段向量对应的字段的层级遍历等,优选的,可以按照字段对应的层级或字段向量对应的层级进行遍历,先读取层级小的字段或字段向量,再读取层级大的。
[0079]
步骤s133:若满足结束条件,得到目标数据,否则,继续执行目标字段构建的步骤。其中,结束条件包括以下一项:源数据中各个字段均已作为过当前源字段、转换映射关系中各第一字段向量均已作为过当前第一字段向量、第二字段向量集合中各第二字段向量均已作为过当前第二字段向量。
[0080]
在执行了一次s132后,判断是否满足结束条件。若满足,则说明已遍历完毕,得到目标数据。若不满足,说明未遍历完毕,需要继续通过s132进行遍历。
[0081]
在第一次执行构建目标字段的步骤时,可以读取源数据,获得当前源字段,然后从第二字段向量集合中获取当前源字段对应的当前第二字段向量,或者,还可以从第一字段向量集合确定当前第一字段向量,然后即可获得当前第一字段向量对应的当前源字段,进而获取当前第一字段向量对应的第二字段向量,或者,还可以从第二字段向量集合中确定当前第二字段向量,进而获取当前第二字段向量对应的当前第一字段向量,以及获得当前第一字段向量对应的当前源字段。也即,不管哪种方式“触发构建”,均可获得当前源字段、当前第二字段向量和当前第一字段向量。结束条件中的三项对应触发构建的三种方式(维度)。
[0082]
在第一次执行构建目标字段的步骤时,如当前源字段为key,获得其对应的当前第一字段向量x0,然后在第一字段向量集合中,获取x0的索引值x,然后可到映射表中获取x被映射后的索引值y,根据索引值y,获取当前第一字段向量对应的当前第二字段向量y0=f
(x0),然后可根据y0在初始化的目标数据中构造当前目标字段key’,此时获得的目标数据包含了当前目标字段key’。
[0083]
判断不满足结束条件,因此可继续上述构建目标字段过程,第二次执行构建目标字段步骤时,是在上一次(第一次)获得的目标数据中构建,重复上述过程,直至满足结束条件。并且,每次遍历获得的当前源字段、当前第二字段向量均不同,即每个源字段、每个第二字段向量只会遍历一次,这样即可提高字段的构建效率(多个不同当前源字段对应同一第一字段向量、进而对应同一第二字段向量的情形除外,此时同一第二字段向量可能被遍历多次,此时,优选从源字段维度进行遍历,此时如果从第一字段向量、第二字段向量的维度进行遍历,可能出现某些源字段未被遍历到的情况)。
[0084]
在上述实施例的基础上,在另一实施例中,步骤s3可以包括s31和s32中的至少一者:
[0085]
步骤s31:若目标数据中存在当前第二字段向量所对应字段的当前父节点且当前父节点中不存在当前第二字段向量所对应的当前目标字段,则在当前父节点下添加当前目标字段。
[0086]
优选的,步骤s31在当前父节点对应的字段的类型为对象类型时执行。
[0087]
例如,以表2为例,若当前源字段为key2,对应的第一字段向量为x3,对应第二字段向量为x6’,第二字段向量所对应的当前目标字段为item2,其父节点为item5,即存在父节点,字段item5的类型为对象,若目标数据中此时父节点item5中不存在字段item2,则可将当前目标字段item2添加到该父节点item5下。
[0088]
需要说明的是,在构建当前目标字段key’时,针对key’={l,k,t,p}(层级、名称、类型、父节点),获取key’的父节点parent,即字段向量中,level=l

1,name=p的字段向量。父节点parent的类型只能是object或array,因为string、bool、number类型的数据没有子节点,也就是说,当前目标字段key’只能构建在类型为object或array的父节点下。
[0089]
步骤s32:若当前第二字段向量所对应字段的当前父节点对应的字段的类型为数组时,当前目标字段添加步骤包括以下至少一项:
[0090]
若目标数据中存在当前第二字段向量所对应字段的当前父节点且当前父节点的最后一个数组元素中不存在当前第二字段向量所对应字段对应的当前目标字段,则在当前父节点的最后一个数组元素下添加当前目标字段;若目标数据中存在当前第二字段向量所对应字段的当前父节点且当前父节点的最后一个数组元素中存在当前第二字段向量所对应字段对应的当前目标字段,则在当前父节点的最后一个数组元素之后新建一个数组元素,在新建的数组元素下添加当前目标字段。
[0091]
也就是说,若目标数据中当前第二字段向量所对应字段已经存在当前父节点,如果当前父节点对应的字段是数组类型,且数组元素的类型是object,则判断当前父节点的最后一个数组元素内是否存在当前目标字段key’,如果不存在,就直接将key’添加到最后一个数组元素下,如果存在,则新建一个数组元素,如新建空的对象,将key’添加到该数组元素下。如果当前父节点的数组元素的类型是string、bool、number、array(array符合前文限制条件)类型,则不会对数组元素进行遍历,不会出现当前父节点parent为array的情况,所以这种情况在本文不会出现。所以,若当前父节点parent为array,则其数组元素的类型为object。
[0092]
可以理解的是,步骤s31和步骤s32只在合适位置添加了目标字段,并未给目标字段赋值,因此在通过步骤s31或步骤s32添加当前目标字段之后,步骤s3还包括:
[0093]
步骤s33:若当前第二字段向量的类型为对象类型,或者,若当前第二字段向量的类型为数组类型且数组元素为对象类型,则将当前目标字段的字段值初始化为空;若当前第二字段向量的类型为值类型,或者,若当前第二字段向量的类型为数组类型且数组元素为值类型,则根据当前源字段的字段值确定当前目标字段的字段值。
[0094]
第二字段向量的类型,是指第二字段向量所对应字段的类型。
[0095]
可以理解的是,若当前第二字段向量的类型为对象类型,或者,若当前第二字段向量的类型为数组类型且数组元素为对象类型,当前第二字段向量对应的字段还有子节点,其字段值需要在构建子节点时确定,因此只需将其字段值初始化为空。若当前第二字段向量的类型为值类型,或者,若当前第二字段向量的类型为数组类型且数组元素为值类型,则将源字段的字段值直接或经格式转换后作为当前第二字段向量对应的字段的字段值,无需在构建子节点时确定。
[0096]
例如,如果当前目标字段key’是object类型,或者当前目标字段key’为array类型且数组元素为object类型时,则初始化key’等于空的对象,即将当前目标字段key’的字段值初始化为空。若key’的元素类型为array类型且数组元素为值类型或者key’的类型为值类型,则初始化key’等于原始key的取值,也就是说将当前源字段key的字段值确定为当前目标字段key’的字段值。
[0097]
在上述实施例的基础上,在确定当前目标字段的字段值时,还可以比较当前源字段的类型和当前第二字段向量的类型是否一致,如果不一致,则将当前源字段的字段值转换为当前第二字段向量的类型或报错。
[0098]
例如,如果当前源字段key的类型为string,当前第二字段向量的类型为值类型,则可将key的字段值转换为值类型,或者拒绝转换并报错,如此可提醒用户查看报错的原因,进而可对转换过程进行核查。
[0099]
在上述实施例的基础上,在目标数据中存在当前字段的父节点时,通过步骤s31或s32在当前字段的父节点下添加当前目标字段,在目标数据中不存在当前目标字段的父节点时,需要先在目标数据中构建当前目标字段的父节点,再通过步骤s31或s32在目标数据的当前父节点下添加当前目标字段。
[0100]
因此,一个具体实施方式中,步骤s3还包括构建当前父节点的步骤s30。步骤s30包括:
[0101]
步骤s301:若目标数据中不存在当前第二字段向量所对应字段的当前父节点,则判断目标数据中是否存在当前父节点的父节点;
[0102]
步骤s302:若目标数据中存在当前父节点的父节点且当前父节点的父节点对应的字段为对象类型,则在当前父节点的父节点下添加当前父节点对应的字段并将当前父节点所对应字段的字段值初始化为空;和/或
[0103]
步骤s303:若目标数据中存在当前父节点的父节点且当前父节点的父节点对应的字段为数组类型,则在当前父节点的最后一个数组元素下添加当前父节点对应的字段并将当前父节点所对应字段的字段值初始化为空。
[0104]
也就是说,在构建当前目标字段key’时,先在目标数据中查找是否存在当前目标
字段key’的父节点,如不存在,则继续寻找是否存在当前父节点的父节点,直到某个父节点已经生成(初始化时根节点已经生成,最差的情况,某个父节点是根节点,根节点已生成),然后依次把没有生成的父节点、祖父节点、曾祖父节点等父节点倒序生成,直至生成当前目标字段key’的父节点。生成当前目标字段的父节点后,再通过步骤s31或s32在父节点下添加当前目标字段。
[0105]
在倒序生成父节点的过程中,在生成当前父节点的父节点后,若当前父节点的父节点对应的字段为对象类型,则在当前父节点的父节点下添加当前父节点的字段并将字段值初始化为空,然后再将当前目标字段添加到当前父节点下。若是当前父节点的父节点对应的字段为数组类型,则在当前父节点的最后一个数组元素下添加当前父节点对应的字段并将字段值初始化为空。可以理解的是,由于当前父节点一定具有子节点(当前目标字段对应的节点),当前父节点对应的字段的字段值通过其子节点的构建步骤确定,在此初始化为空即可。
[0106]
在上述实施例的基础上,在对源数据进行转换得到目标数据的过程中,可通过特殊的遍历方式减少上述递归查找父节点再倒序构建的次数,从而提高转换效率。具体的,可以通过如下两种遍历方式:
[0107]
方式一:步骤s130包括:
[0108]
获取初始化的目标数据,所述初始化的目标数据具有根节点;
[0109]
取i为1;
[0110]
执行目标字段构建步骤:若第二字段向量集合中有层级为i的字段对应的第二字段向量未作为过当前第二字段向量,则从未作为过当前第二字段向量中取层级为i的字段对应的一个第二字段向量作为当前第二字段向量,否则将i 1作为新的i并从第二字段向量集合中取层级为新的i的字段对应的未作为过当前第二字段向量的一个第二字段向量作为当前第二字段向量;根据所述转换映射关系,确定当前第二字段向量对应的当前第一字段向量;从所述源数据的字段中确定当前第一字段向量对应的字段作为当前源字段;根据所述当前第二字段向量和/或所述当前源字段,在目标数据中构建所述当前第二字段向量对应的当前目标字段;
[0111]
若满足结束条件,得到目标数据;否则,继续执行所述目标字段构建的步骤;其中,所述结束条件包括:所述第二字段向量集合中各第二字段向量均已作为过当前第二字段向量。
[0112]
递归遍历时,先初始化层级i等于1,从层级为1的字段开始遍历,如果是对第二字段向量进行遍历,则先遍历层级为1的第二字段向量,然后按照上述的目标字段的构建方式构建目标字段。如果此时层级为1的第二字段向量为1个时,则继续取i为2,若层级为2的第二字段向量为3个时,则获取其中一个第二字段向量作为当前第二字段向量,然后按照上述的方式构建当前第二向量对应的当前目标字段。然后继续将层级为2的另一个第二字段向量作为当前第二字段向量,继续构建目标字段。然后再将层级为2的最后一个第二字段向量作为当前第二字段向量,构建目标字段,直至将层级为2的第二字段向量遍历完一遍,每个第二字段向量只能有一次作为当前第二字段向量,即不能重复作为当前第二字段向量。将层级为2的第二字段向量遍历完、构建目标字段后,取i为3,即继续遍历层级为3的第二字段向量,重复执行上述过程,直至遍历到最后一个第二字段向量。
[0113]
方式二:步骤s130包括:
[0114]
获取初始化的目标数据,所述初始化的目标数据具有根节点;
[0115]
取i为1;
[0116]
执行目标字段构建步骤(包括步骤sa

sd):
[0117]
sa:判断是否存在未作为过当前目标字段的指定的当前源字段;
[0118]
若不存在,如果所述源数据中有未作为过当前目标字段且层级为i的字段,则从该字段中选取一个字段作为当前源字段,否则将i 1作为新的i并从源数据中未作为过当前目标字段且层级为新的i的字段中选取一个字段作为当前源字段;
[0119]
若存在,则将指定的源字段作为当前源字段;
[0120]
sb:根据所述转换映射关系,确定所述当前源字段对应的当前第二字段向量;其中,所述当前源字段对应的当前第一字段向量和所述当前第二字段向量之间具有映射关系;
[0121]
sc:根据所述当前第二字段向量和/或所述当前源字段,在目标数据中构建所述当前第二字段向量对应的当前目标字段;
[0122]
sd:判断当前目标字段是否是其他字段的父节点,如果是,则将所述其他字段依次作为指定的当前源字段;
[0123]
若满足结束条件,得到目标数据;否则,继续执行所述目标字段构建的步骤;其中,所述结束条件包括:所述源数据中各个字段均已作为过当前源字段。
[0124]
举例来说,以golang编程语言为例,源数据中字段与字段向量的对应关系已经第一字段向量与第二字段向量的转换映射关系用<k,v>映射表(map)进行存储,<k,v>是键值对,k存储了具有第一数据结构的json数据(第一类数据)的字段名称,v存储了该字段名称对应的第二字段向量,通过k即可获取v。下面叙述从map存储池递归遍历,得到目标数据的方法,包括:
[0125]
初始化递归流程:recursive(features,jsonmap,level,parent),其中features为解析得到的字段向量存储器,初始化为空的数组,jsonmap即json数据在golang当中的存储池,是一个map映射表,level即当前要读取的字段的层级,初始化为1,parent即父节点,初始化为root。
[0126]
然后进入递归流程,遍历jsonmap的所有字段key1,key2,...,keyn(这些字段的层级均为1),每读取到一个字段,判断keyi(i=1,2,...,n)的类型(通常也是其所对应目标字段的类型),若是string,bool,number类型,且该字段对应的第二字段向量对应的当前目标字段不存在于目标数据中,则将feat={level,keyi,type,parent}(type代表keyi的类型)添加到features中;若是object类型,且该字段对应的第二字段向量对应的当前目标字段不存在于目标数据中,则将feat={level,keyi,object,parent}添加到features中,进入下一个递归流程:取i为2,recursive(features,valuei,level 1,keyi)(根据map映射表的说明,通过keyi可以获取valuei,valuei代表keyi对应的第二字段向量);若是array类型,则遍历array的每个元素,若数组不满足前文的限制条件,则报告错误,不支持这种数组,将feat={level,keyi,array,parent,subtype}添加到features中,当subtype=object时依次进入递归recursive(features,elemi,level 1,keyi)(elemi代表当前元素)。
[0127]
递归流程完成时,若没有错误,features就是目标数据。
[0128]
下面以具体的示例来对上述的转换过程进行说明。
[0129]
示例1:如表3所示的第一类数据和第二类数据:
[0130]
表3
[0131][0132][0133]
然后构造第一字段向量到第二字段向量之间的映射函数f,如表4所示。
[0134]
表4
[0135][0136]
遍历第一类数据,针对每个字段key,到映射表f中获取key的索引x0所映射的字段向量y0=(x0),根据y0构造第二类数据的目标字段key’,具体过程如下:
[0137]
层级i=1:遍历“example”,对应的第一字段向量x1,对应于第二字段向量x2’=test={1,test,object,root},针对x2’,获取x2’的父节点parent=root,由于把目标数据初始化为空的对象,所以可以直接把test添加到root节点下面,test取值等于空的对象。
[0138]
层级i=2:
[0139]
遍历“key1”,对应的第一字段向量x2,对应于第二字段向量x1’=item1={1,item1,string,root},针对x1’,获取x1’的父节点parent=root,把item1添加到root节点下面,取值为“key1”的值,也就是“字符串”;
[0140]
遍历“key2”,对应的第一字段向量x3,对应于第二字段向量x6’=item2={2,item2,bool,item5},针对x6’,获取x6’的父节点parent=item5,由于父节点item5={1,item5,object,root},没有创建,则获取祖父节点为root。在root下面创建item5,取值为空的对象“{}”,然后把item2添加到item5节点下面,类型为bool,取值等于“key2”的值,即true;
[0141]
遍历“key3”,对应的第一字段向量x4,对应于第二字段向量x3’=item3={2,item3,number,test},针对x3’,获取x3’的父节点parent=test,由于父节点test={1,test,object,root},已经创建,则把item3添加到test节点下面,类型为number,取值等于“key3”的值,即10;
[0142]
遍历“key4”,对应的第一字段向量x5,对应于第二字段向量x4’=item4={2,item4,array,test,number},针对x4’,获取x4’的父节点parent=test,由于父节点test={1,test,object,root},已经创建,则把item4添加到test节点下面,item4类型为array,且元素类型为number,取值等于“key4”的值,即[1,2,3];
[0143]
遍历“key5”,对应的第一字段向量x6,对应于第二字段向量x5’=item5={1,item5,object,root},针对x5’,获取x5’的父节点parent=root,由于父节点已经创建,则不用再次创建。
[0144]
层级i=3:遍历“key6”,对应的第一字段向量x7,对应于第二字段向量x7’=item6={2,item6,number,item5},针对x7’,获取x7’的父节点parent=item5={1,item5,object,root},由于父节点已经创建,则在item5下面新增item6,取值等于“key6”的值,即9。
[0145]
上述是将属于第一类数据的源数据转换为属于第二类数据的目标数据的示例,对于将属于第二类数据的源数据转换为属于第一类数据的目标数据的方式也同理。
[0146]
示例2:如表5所示的第一类数据和第二类数据:
[0147]
表5
[0148][0149]
然后构造第一字段向量到第二字段向量之间的映射函数f,如表6所示。
[0150]
表6
[0151]
第一类数据x1x2x3x4x5第二类数据x1’x2’x5’x4’x3’[0152]
然后遍历第一字段向量集合中的各个第一字段向量对应的字段:
[0153]
遍历“array1”,对应的第一字段向量x1,对应于第二字段向量x1’=a1={1,a1,array,root,object},针对x1’,获取x1’的父节点parent=root。因为x1’的元素类型为object,x1’未创建则初始化a1等于空的数组;
[0154]
遍历“key1”,对应的第一字段向量x2,对应于第二字段向量x2’=key1={2,key1,string,a1},针对x2’,获取x2’的父节点parent=a1,判断key1是否已存在于最后一个数组元素内,如果不存在,就添加到最后一个元素内;如果存在则新建空的对象,把key1添加到该对象,再把该对象追加到数组后面;因为数组a1为空,所以新增一个空的对象,再把key1添加到该对象,再把该对象追加到数组后面;a1的第一个元素为{“key1”:“字符串1”};
[0155]
遍历“key2”,对应的第一字段向量x3,对应于第二字段向量x5’=key2={2,key2,string,a2},针对x5’,获取x5’的父节点parent=a2,父节点不存在,寻找祖父节点为x4’=a2={1,a2,array,root,object},生成祖父节点,初始化为空的数组;然后判断key2是否已
存在于最后一个数组元素内,如果不存在,就添加到最后一个元素内;如果存在则新建空的对象,把key2添加到该对象,再把该对象追加到数组后面;因为数组a2为空,所以新增一个空的对象,再把key2添加到该对象,再把该对象追加到数组后面;a2的第一个元素为{“key2”:“字符串2”};
[0156]
遍历“array2”,对应的第一字段向量x4,对应于第二字段向量x4’=a2={1,a2,array,root,object},针对x4’,获取x4’的父节点parent=root,已经生成,不用管。
[0157]
遍历“key3”,对应的第一字段向量x5,对应于第二字段向量x5’=key2={2,key2,string,a2},针对x5’,获取x5’的父节点parent=a2,已经生成;然后判断key3是否已存在于最后一个数组元素内,因为不存在,就添加到最后一个元素内;a1的第一个元素更新为{“key1”:“字符串1”,“key3”:“字符串3”}。
[0158]
所以,对于一种类型的json数据,将该类型的json数据结构进行打乱n次,即可得到n种数据类型的json数据,然后只需建立从原始的json数据到打乱后的json数据之间的<k,v>映射关系,就能实现对这其中任意2种数据之间的转换。如果映射关系不是满射,则可能出现目标json的字段覆盖不全或原始json的字段未被用到的情况。
[0159]
在一些实施方式中,为了便于在进行转换时可以快速获得对应的转换映射关系,可以根据数据发送方与数据接收方所需的转换映射关系来存储映射关系,如数据接收方在获得源数据时,还可以从源数据中获取其携带的数据发送方的标识信息,然后可根据数据发送方的标识信息查找获得对应的转换映射关系,或者,数据发送方在发送数据时,可以获取数据接收方的标识信息,然后可根据数据接收方的标识信息查找获得对应的转换映射关系,从而可根据该转换映射关系完成数据的转换。
[0160]
请参照图3,图3为本技术实施例提供的一种数据转换装置200的结构框图,该装置200可以是电子设备上的模块、程序段或代码。应理解,该装置200与上述图1方法实施例对应,能够执行图1方法实施例涉及的各个步骤,该装置200具体的功能可以参见上文中的描述,为避免重复,此处适当省略详细描述。
[0161]
可选地,所述装置200包括:
[0162]
映射关系获取模块210,用于获取第一类数据与第二类数据之间的转换映射关系,所述转换映射关系是指所述第一类数据对应的第一字段向量集合中的多个第一字段向量与所述第二类数据对应的第二字段向量集合中的多个第二字段向量之间的映射关系,其中,所述多个第一字段向量是指与所述第一类数据中的字段具有对应关系的向量,所述第一字段向量中的不同元素用于表征其所对应字段的不同字段特征;所述多个第二字段向量是指与所述第二类数据中的字段具有对应关系的向量,所述第二字段向量中的不同元素用于表征其所对应字段的不同字段特征;所述字段特征包括字段的层级、名称、类型、父节点中的至少两个;
[0163]
数据获取模块220,用于获取源数据,所述源数据属于所述第一类数据;
[0164]
转换模块230,用于根据所述转换映射关系,对所述源数据进行转换,得到目标数据,所述目标数据属于所述第二类数据。
[0165]
可选地,所述转换模块230,用于:
[0166]
获取初始化的目标数据,所述初始化的目标数据具有根节点;
[0167]
目标字段构建步骤:从所述源数据中确定当前源字段;从所述第二字段向量集合
中确定当前第二字段向量;其中,所述当前源字段对应的当前第一字段向量和所述当前第二字段向量之间具有映射关系;根据所述当前第二字段向量和/或所述当前源字段,在目标数据中构建所述当前第二字段向量对应的当前目标字段;
[0168]
若满足结束条件,得到目标数据;否则,继续执行所述目标字段构建的步骤;其中,所述结束条件包括以下一项:所述源数据中各个字段均已作为过当前源字段、所述转换映射关系中各第一字段向量均已作为过当前第一字段向量、所述第二字段向量集合中各第二字段向量均已作为过当前第二字段向量。
[0169]
可选地,所述转换模块230,用于若目标数据中存在所述当前第二字段向量所对应字段的当前父节点且所述当前父节点中不存在当前第二字段向量所对应的当前目标字段,则在所述当前父节点下添加所述当前目标字段。
[0170]
可选地,所述转换模块230,用于执行当前目标字段添加步骤;所述当前目标字段添加步骤包括以下至少一项:
[0171]
若目标数据中存在所述当前第二字段向量所对应字段的当前父节点且所述当前父节点的最后一个数组元素中不存在当前第二字段向量所对应字段对应的当前目标字段,则在所述当前父节点的最后一个数组元素下添加所述当前目标字段;
[0172]
若目标数据中存在所述当前第二字段向量所对应字段的当前父节点且所述当前父节点的最后一个数组元素中存在当前第二字段向量所对应字段对应的当前目标字段,则在所述当前父节点的最后一个数组元素之后新建一个数组元素,在新建的数组元素下添加所述当前目标字段。
[0173]
可选地,在添加所述当前目标字段之后,所述转换模块230,还用于若当前第二字段向量的类型为对象类型,或者,若所述当前第二字段向量的类型为数组类型且数组元素为对象类型,将当前目标字段的字段值初始化为空;若当前第二字段向量的类型为值类型,或者,若所述当前第二字段向量的类型为数组类型且数组元素为值类型,根据当前源字段的字段值确定当前目标字段的字段值。
[0174]
可选地,所述转换模块230,还用于比较当前源字段的类型和所述当前第二字段向量的类型是否一致,如果不一致,则将当前源字段的字段值转换为当前第二字段向量的类型或报错。
[0175]
可选地,所述当前目标字段添加步骤之前,所述转换模块230,还用于若目标数据中不存在所述当前第二字段向量所对应字段的当前父节点,则判断目标数据中是否存在所述当前父节点的父节点;若目标数据中存在所述当前父节点的父节点且所述当前父节点的父节点对应的字段为对象类型,则在所述当前父节点的父节点下添加所述当前父节点对应的字段并将所述当前父节点所对应字段的字段值初始化为空;或者若目标数据中存在所述当前父节点的父节点且当前父节点的父节点对应的字段为数组类型,则在所述当前父节点的最后一个数组元素下添加所述当前父节点对应的字段并将所述当前父节点所对应字段的字段值初始化为空。
[0176]
可选地,所述转换模块230,用于:
[0177]
获取初始化的目标数据,所述初始化的目标数据具有根节点;
[0178]
取i为1;
[0179]
执行目标字段构建步骤:若第二字段向量集合中有层级为i的字段对应的第二字
段向量未作为过当前第二字段向量,则从未作为过当前第二字段向量中取层级为i的字段对应的一个第二字段向量作为当前第二字段向量,否则将i 1作为新的i并从第二字段向量集合中取层级为新的i的字段对应的未作为过当前第二字段向量的一个第二字段向量作为当前第二字段向量;根据所述转换映射关系,确定当前第二字段向量对应的当前第一字段向量;从所述源数据的字段中确定当前第一字段向量对应的字段作为当前源字段;根据所述当前第二字段向量和/或所述当前源字段,在目标数据中构建所述当前第二字段向量对应的当前目标字段;
[0180]
若满足结束条件,得到目标数据;否则,继续执行所述目标字段构建的步骤;其中,所述结束条件包括:所述第二字段向量集合中各第二字段向量均已作为过当前第二字段向量。
[0181]
可选地,所述转换模块230,用于:
[0182]
获取初始化的目标数据,所述初始化的目标数据具有根节点;
[0183]
取i为1;
[0184]
执行目标字段构建步骤:
[0185]
判断是否存在未作为过当前目标字段的指定的当前源字段;
[0186]
若不存在,如果所述源数据中有未作为过当前目标字段且层级为i的字段,则从该字段中选取一个字段作为当前源字段,否则将i 1作为新的i并从源数据中未作为过当前目标字段且层级为新的i的字段中选取一个字段作为当前源字段;
[0187]
若存在,则将指定的源字段作为当前源字段;
[0188]
根据所述转换映射关系,确定所述当前源字段对应的当前第二字段向量;其中,所述当前源字段对应的当前第一字段向量和所述当前第二字段向量之间具有映射关系;
[0189]
根据所述当前第二字段向量和/或所述当前源字段,在目标数据中构建所述当前第二字段向量对应的当前目标字段;
[0190]
判断当前目标字段是否是其他字段的父节点,如果是,则将所述其他字段依次作为指定的当前源字段;
[0191]
若满足结束条件,得到目标数据;否则,继续执行所述目标字段构建的步骤;其中,所述结束条件包括:所述源数据中各个字段均已作为过当前源字段。
[0192]
需要说明的是,本领域技术人员可以清楚地了解到,为描述的方便和简洁,上述描述的装置的具体工作过程,可以参考前述方法实施例中的对应过程,在此不再重复描述。
[0193]
请参照图4,图4为本技术实施例提供的一种用于执行数据转换方法的电子设备的结构示意图,所述电子设备可以包括:至少一个处理器310,例如cpu,至少一个通信接口320,至少一个存储器330和至少一个通信总线340。其中,通信总线340用于实现这些组件直接的连接通信。其中,本技术实施例中设备的通信接口320用于与其他节点设备进行信令或数据的通信。存储器330可以是高速ram存储器,也可以是非易失性的存储器(non

volatile memory),例如至少一个磁盘存储器。存储器330可选的还可以是至少一个位于远离前述处理器的存储装置。存储器330中存储有计算机可读取指令,当所述计算机可读取指令由所述处理器310执行时,电子设备执行上述图1所示方法过程。
[0194]
可以理解,图4所示的结构仅为示意,所述电子设备还可包括比图4中所示更多或者更少的组件,或者具有与图4所示不同的配置。图4中所示的各组件可以采用硬件、软件或
其组合实现。
[0195]
本技术实施例提供一种可读存储介质,所述计算机程序被处理器执行时,执行如图1所示方法实施例中电子设备所执行的方法过程。
[0196]
本实施例公开一种计算机程序产品,所述计算机程序产品包括存储在非暂态计算机可读存储介质上的计算机程序,所述计算机程序包括程序指令,当所述程序指令被计算机执行时,计算机能够执行上述各方法实施例所提供的方法,例如,包括:获取第一类数据与第二类数据之间的转换映射关系,所述转换映射关系是指所述第一类数据对应的第一字段向量集合中的多个第一字段向量与所述第二类数据对应的第二字段向量集合中的多个第二字段向量之间的映射关系,其中,所述多个第一字段向量是指与所述第一类数据中的字段具有对应关系的向量,所述第一字段向量中的不同元素用于表征其所对应字段的不同字段特征;所述多个第二字段向量是指与所述第二类数据中的字段具有对应关系的向量,所述第二字段向量中的不同元素用于表征其所对应字段的不同字段特征;所述字段特征包括字段的层级、名称、类型、父节点中的至少两个;获取源数据,所述源数据属于所述第一类数据;根据所述转换映射关系,对所述源数据进行转换,得到目标数据,所述目标数据属于所述第二类数据。
[0197]
综上所述,本技术实施例提供一种数据转换方法、装置、电子设备及可读存储介质,通过获取第一类数据和第二类数据之间的转换映射关系,并根据转换映射关系将源数据转换为目标数据,如此可自动实现数据转换,从而可避免人工转换导致的耗时长、效率低的问题,还可避免人工转换导致的错误率高的问题。
[0198]
在本技术所提供的实施例中,应该理解到,所揭露装置和方法,可以通过其它的方式实现。以上所描述的装置实施例仅仅是示意性的,例如,所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,又例如,多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。
[0199]
另外,作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部单元来实现本实施例方案的目的。
[0200]
再者,在本技术各个实施例中的各功能模块可以集成在一起形成一个独立的部分,也可以是各个模块单独存在,也可以两个或两个以上模块集成形成一个独立的部分。
[0201]
在本文中,诸如第一和第二等之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。
[0202]
以上所述仅为本技术的实施例而已,并不用于限制本技术的保护范围,对于本领域的技术人员来说,本技术可以有各种更改和变化。凡在本技术的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本技术的保护范围之内。
转载请注明原文地址:https://doc.8miu.com/index.php/read-1722296.html

最新回复(0)