吳家菊 紀(jì)斌 劉振吉 陳泉根



摘 ?要: 為設(shè)計(jì)與實(shí)現(xiàn)XML通用數(shù)據(jù)編輯框架中編輯數(shù)據(jù)的驗(yàn)證,提出一種將XML Schema文檔轉(zhuǎn)化為Java代碼的算法。研究XML Schema的元素和元素間嵌套關(guān)系的定義規(guī)則,在此基礎(chǔ)上定義元素到Java代碼的轉(zhuǎn)換規(guī)則和轉(zhuǎn)換算法。該算法以Schema元素為根元素,采用深度優(yōu)先搜索算法遍歷XML Schema文檔的每個(gè)元素,保證對(duì)XML Schema文檔轉(zhuǎn)換的完整性。算法實(shí)現(xiàn)了XML Schema定義的28種元素和12種限定元素到Java代碼的轉(zhuǎn)換,并且元素間的嵌套關(guān)系也得到完整的保存。最后通過轉(zhuǎn)換實(shí)例驗(yàn)證了該算法的正確性和有效性。
關(guān)鍵詞: 可擴(kuò)展標(biāo)記語言模式; Java; 轉(zhuǎn)換; 元素; 類; 解析單元; 創(chuàng)建單元
中圖分類號(hào): TN911?34; TP311 ? ? ? ? ? ? ? ? ? ? ?文獻(xiàn)標(biāo)識(shí)碼: A ? ? ? ? ? ? ? ? ? 文章編號(hào): 1004?373X(2019)11?0169?05
Abstract: In order to design and implement the universal data?editing framework of XML (extensible makeup language) schema, an algorithm to transform XML Schema document into Java code is proposed. The definition rules of elements and their nested relation of XML Schema are studied. On this basis, the transformation rules and transformation algorithm from elements to Java code are defined. Taking schema element as the root element, the deep first search algorithm is used to traverse each element of XML Schema document, which can ensure the completeness of XML Schema document transformation. The transformation from twenty?eight kinds of elements defined by XML Schema and twelve kinds of facet elements to Java code is realized by means of the algorithm, and the nested relation between elements can be reserved completely. The correctness and validity of the algorithm are verified with an transformation instance.
Keywords: extensible makeup language schema; Java; transformation; element; class; analysis unit; creation unit
0 ?引 ?言
武器裝備綜合保障數(shù)據(jù)應(yīng)用于武器裝備綜合保障系統(tǒng)中,在將綜合保障數(shù)據(jù)應(yīng)用于綜合保障系統(tǒng)之前,數(shù)據(jù)需要編輯成XML(eXtensible Markup Language)格式[1]。XML Schema用來設(shè)計(jì)、約束、驗(yàn)證XML,并且在武器裝備綜合保障系統(tǒng)中得到廣泛的應(yīng)用[2]。因此,一種有效的將XML Schema轉(zhuǎn)換為編程語言的算法是數(shù)據(jù)編輯軟件開發(fā)的基礎(chǔ)。
由于XML Schema的文本特性和XML語法的復(fù)雜性,XML Schema文檔定義非常復(fù)雜[3]。在深入研究了W3C Recommendation發(fā)布的XML Schema最新標(biāo)準(zhǔn)的基礎(chǔ)上,本文提出一種將XML Schema文檔轉(zhuǎn)換為Java代碼的轉(zhuǎn)換算法。算法深度優(yōu)先遍歷(Deep First Search,DFS)XML Schema文檔,對(duì)于每個(gè)元素,為其創(chuàng)建一個(gè)Java對(duì)象,并依據(jù)元素之間的嵌套關(guān)系在創(chuàng)建的Java對(duì)象間建立引用關(guān)系。XML Schema文檔經(jīng)過算法轉(zhuǎn)換最終得到一個(gè)根元素schema的Java對(duì)象,該對(duì)象中保存了為所有其他XML Schema文檔包含的元素創(chuàng)建的對(duì)象。XML Schema標(biāo)準(zhǔn)定義了30種元素和12種限定元素[4?5],算法可以實(shí)現(xiàn)其中的28種元素和12種限定元素到Java代碼的轉(zhuǎn)換。該算法具有通用性,可以應(yīng)用到其他XML領(lǐng)域。
1 ?XML Schema元素的定義規(guī)則
W3C Recommendation發(fā)布的XML Schema最新標(biāo)準(zhǔn)中定義了30種元素和12種限定元素。從武器裝備綜合保障領(lǐng)域出發(fā),根據(jù)實(shí)際應(yīng)用需求,在設(shè)計(jì)算法時(shí)將一些元素和元素的屬性排除在外。算法設(shè)計(jì)未包含的元素有anyAttribute和notation。算法設(shè)計(jì)未包含的元素屬性如下:所有元素的ID和anyAttributes屬性;element的nillable,block,final屬性;schema的blockDefault,finalDefault,version屬性。
除元素外,XML Schema定義了12種用于對(duì)元素和屬性取值進(jìn)行約束的限定元素。所有限定元素的父元素均為restriction,都有一個(gè)必選的value屬性和一個(gè)可選的fixed屬性。
2 ?算法設(shè)計(jì)
XML Schema文檔遵循XML語法,因此,DOM(Document Object Model)[6?8]和SAX(Simple API for XML)[9]都可以用來解析XML Schema文檔。該算法采用DOM解析XML Schema文檔。
2.1 ?設(shè)計(jì)思想
從結(jié)構(gòu)上將算法分為解析單元和Java對(duì)象創(chuàng)建單元兩部分。
解析單元首先用Java語言實(shí)現(xiàn)DOM應(yīng)用編程接口,并獲取DOM解析器實(shí)例。其次,解析器解析XML Schema文檔。解析結(jié)果是一個(gè)Document的實(shí)例。獲取解析結(jié)果的第一個(gè)元素,將其命名為[n](對(duì)于一個(gè)格式良好且非空的XML Schema文檔,元素[n]實(shí)際為schema元素。最后,將元素[n]作為參數(shù)傳遞給Java對(duì)象創(chuàng)建單元。
Java對(duì)象創(chuàng)建單元接收解析單元傳遞的元素[n]并獲取[n]的localName,然后調(diào)用與localName對(duì)應(yīng)的Java類的構(gòu)造函數(shù),為元素[n]創(chuàng)建一個(gè)Java對(duì)象。
2.2 ?算法描述
本節(jié)詳細(xì)描述了Java對(duì)象創(chuàng)建單元的執(zhí)行過程,將執(zhí)行過程分為8個(gè)步驟:
1) 獲取元素[n]的localName,調(diào)用與localName對(duì)應(yīng)的元素類的構(gòu)造函數(shù)。若[n]是schema時(shí),則向構(gòu)造函數(shù)傳入的參數(shù)為([n],null,null);若[n]是除schema外的其他元素,則將([n],this,schema)作為參數(shù)傳入構(gòu)造函數(shù);若[n]是限定元素時(shí),則將([n],this)作為參數(shù)傳入構(gòu)造函數(shù)。其中,schema是元素[n]所屬的XML Schema文檔的根元素,即schema元素的對(duì)象。
2) 若該類是元素類,則將構(gòu)造函數(shù)的第一個(gè)參數(shù)賦值給類中element變量,第二個(gè)參數(shù)賦值給類中parent變量,第三個(gè)參數(shù)賦值給類中schema變量;若該類是Facet類,則將構(gòu)造函數(shù)的第一個(gè)參數(shù)賦值給類中element變量,第二個(gè)參數(shù)賦值給類中parent變量。
3) 依次執(zhí)行元素的每個(gè)屬性定義的屬性判別語句,完成元素屬性的處理。
4) 獲取元素[n]的第一個(gè)子元素[n′]。
5) 若([n′] != null)為真,則執(zhí)行第7)步;若為假,元素[n′]的父元素[n]的對(duì)象創(chuàng)建完成,執(zhí)行第6)步。
6) 若([n.] getLocalName==“schema”)為真,則XML Schema文檔中包含的所有元素的對(duì)象創(chuàng)建完成,程序正常結(jié)束;若為假,則首先將創(chuàng)建的元素[n]的對(duì)象賦值給元素[n]的父元素類中為[n]創(chuàng)建的變量,然后獲取直接在元素[n]之后的元素[n′],執(zhí)行第5)步(注意:用獲取的元素[n′]替換第5)步中的元素[n′])。
7) 若([n′] instance of Element==true)為真,則執(zhí)行第1)步(注意:用獲取的元素[n′]替換第1)步中的元素[n]);若為假,則執(zhí)行下一步。
8) 獲取直接在元素[n′]之后的元素[n″],執(zhí)行第5)步(注意:用獲取的元素[n″]替換第5)步中的元素[n′])。

3 ?算法實(shí)現(xiàn)
依據(jù)算法的設(shè)計(jì),算法的實(shí)現(xiàn)分為兩部分:解析單元的實(shí)現(xiàn)和Java對(duì)象創(chuàng)建單元的實(shí)現(xiàn)。解析單元是一個(gè)名為Create_XSD_Objects的Java類,該類是算法的主類和入口。Java對(duì)象創(chuàng)建單元包含28種元素和12種限定元素創(chuàng)建的Java類。另外,為提高代碼的重用性和方便地定義變量數(shù)據(jù)類型,定義一組類和接口。
3.1 ?為元素定義Java類
1) 為每種元素定義一個(gè)Java類,以首字母大寫的元素名作為類名。并依據(jù)元素與其子元素的嵌套關(guān)系,在Java類中建立引用關(guān)系。
2) Annotated抽象類:annotation可以出現(xiàn)是任何元素(annotation, documentation,appinfo除外)的子元素。為提高代碼的重用性,定義一個(gè)名為”Annotated”的抽象類。除了Annotation,Documentation,Appinfo三個(gè)Java類外,其他所有元素和限定元素的Java類都繼承該抽象類。圖2描述了Annotated和相關(guān)Java類的UML類圖。

3) Keybase抽象類:Key,Keyref,Unique三種元素的父元素都是element,并且三種元素的子元素相同。不同的是,Keyref可以有ref屬性。為提高代碼重用性,定義一個(gè)名為“Keybase”的抽象類。Key,Keyref,Unique繼承該抽象類,調(diào)用該抽象類中定義的方法為對(duì)應(yīng)的元素創(chuàng)建Java對(duì)象。
4) ExplicitGroup抽象類:sequence和choice兩種元素可以相互嵌套,并且兩種元素的父元素、子元素、屬性均相同,使用規(guī)則也相同。為提高代碼重用性,定義一個(gè)名為“ExplicitGroup”的抽象類。Sequence和Choice繼承該抽象類,調(diào)用該抽象類中定義的方法為對(duì)應(yīng)的元素創(chuàng)建Java對(duì)象。
5) Thing接口:為方便定義Java類中變量的數(shù)據(jù)類型,定義了一個(gè)名為”Thing”的空接口。所有其他Java類實(shí)現(xiàn)該接口。該接口在算法中有如下五種用途。
① 在Group,ComplexType,Extension,Restriction中定義一個(gè)名為“attributes”的變量,變量的數(shù)據(jù)類型為L(zhǎng)ist
② 在Element中定義一個(gè)名為“identifyConstraints”的變量,變量數(shù)據(jù)類型為L(zhǎng)ist
③ 在Redefine中定義一個(gè)名為“redefinables”的變量,變量的數(shù)據(jù)類型為L(zhǎng)ist
④ 在Sequence和Choice中定義一個(gè)名為modelGroup的變量,變量數(shù)據(jù)類型為L(zhǎng)ist
⑤ Thing作為元素的Java類和限定元素的Java類構(gòu)造函數(shù)的第二個(gè)參數(shù)變量的數(shù)據(jù)類型。
3.1.1 ?在Java類中為元素的屬性定義變量
對(duì)于元素包含的每個(gè)屬性,一般來說在元素的Java類中為其定義一個(gè)變量。變量與屬性同名。變量數(shù)據(jù)類型及一些特殊變量定義如下:
1) 在Union中為union的memberTypes屬性定義一個(gè)名為“memberTypes”的變量,變量的數(shù)據(jù)類型為String[],變量的初始值為null。
2) 在Schema中為默認(rèn)名稱空間定義一個(gè)名為“xmlns”的變量,變量的數(shù)據(jù)類型為String。為帶有名稱空間前綴的名稱空間定義一個(gè)名為“namespace”的變量,變量的數(shù)據(jù)類型為HashMap
3) 表1給出了其他一些為元素特殊屬性定義的變量。除去表1列舉的屬性以及上述兩種屬性外,為元素屬性定義的變量數(shù)據(jù)類型為String,變量初始值為null。3.1.2 ?在元素的Java類中為元素的子元素定義變量
除3.1中描述的為元素的子元素定義的特殊變量外,對(duì)于元素其他的子元素,為每個(gè)子元素在元素的Java類中定義一個(gè)變量,變量的定義規(guī)則如下所示:
1) 如果子元素在元素中可以出現(xiàn)0次或1次,在元素的Java類中為子元素定義一個(gè)變量,以子元素名作為變量名,以子元素的Java類作為變量的數(shù)據(jù)類型。
2) 如果子元素在元素中可以出現(xiàn)至少1次或0次到多次,則在元素的Java類中為其定義的變量如表2所示。
3) 在元素的Java類中為每個(gè)子元素創(chuàng)建的變量初始值均為null。
3.1.3 ?在元素的Java類中定義特殊變量
除去上述為元素的屬性和子元素創(chuàng)建的變量外,在元素的Java類中定義了三個(gè)變量:一個(gè)名為element的變量,數(shù)據(jù)類型為Element;一個(gè)名為parent的變量,數(shù)據(jù)類型為Thing;一個(gè)名為schema的變量,數(shù)據(jù)類型為Schema。三個(gè)變量的初始值均為null。
3.1.4 ?在元素的Java類中定義構(gòu)造函數(shù)
每個(gè)元素的Java類都有一個(gè)構(gòu)造函數(shù)。構(gòu)造函數(shù)有三個(gè)參數(shù):第一個(gè)是數(shù)據(jù)類型為Element的element參數(shù);第二個(gè)是數(shù)據(jù)類型為Thing的parent參數(shù);第三個(gè)是數(shù)據(jù)類型為Schema的schema參數(shù)。在構(gòu)造函數(shù)中,定義變量賦值語句,將構(gòu)造函數(shù)的三個(gè)參數(shù)賦值給Java類中定義的相關(guān)變量。另外,在構(gòu)造函數(shù)中定義判斷語句和賦值語句,用于判斷元素包含的屬性和子元素,并將屬性值或子元素的Java對(duì)象賦值給Java類中定義的相關(guān)變量。
3.2 ?為限定元素定義Java類
1) restriction是所有限定元素的唯一父元素,并且所有的限定元素可能包含的屬性相同。為提高代碼的重用性,為所有限定元素定義一個(gè)共用的Java類,以“Facet“作為類名。
2) 在Facet中定義變量:定義一個(gè)名為“facet”的變量,用于存儲(chǔ)限定元素名;一個(gè)名為“value”的變量,對(duì)應(yīng)于限定元素的value屬性;一個(gè)名為“fixed”的變量,對(duì)應(yīng)于限定元素的fixed屬性;一個(gè)名為element的變量,數(shù)據(jù)類型為Element;一個(gè)名為parent的變量,數(shù)據(jù)類型為Thing。facet和value的數(shù)據(jù)類型為String,fixed的數(shù)據(jù)類型為boolean。五個(gè)變量的初始值均為null。
3) 在Facet中定義構(gòu)造函數(shù):Facet的構(gòu)造函數(shù)有兩個(gè)參數(shù),第一個(gè)是數(shù)據(jù)類型為Element的element參數(shù);第二個(gè)是數(shù)據(jù)類型為Thing的parent參數(shù)。在構(gòu)造函數(shù)中定義變量賦值語句,將構(gòu)造函數(shù)參數(shù)賦值給Facet中定義的相關(guān)變量。另外,在構(gòu)造函數(shù)中定義判斷語句和賦值語句,用于判斷限定元素包含的屬性,并將屬性值賦值給Facet中定義的相關(guān)變量。
4 ?轉(zhuǎn)換例子
在本節(jié)中以ATA/ASD/AIA S1000D Issue 4.2定義的descriptSchema.xsd作為轉(zhuǎn)換文檔[10],驗(yàn)證轉(zhuǎn)換算法的正確性和有效性。圖3給出了轉(zhuǎn)換文檔經(jīng)過轉(zhuǎn)換后得到的Java對(duì)象信息的部分輸出結(jié)果。對(duì)比分析輸出信息和源XML Schema文檔可以得出:算法能夠正確和有效地將源文檔中包含的每個(gè)元素轉(zhuǎn)換為Java對(duì)象;算法能夠正確地判斷元素包含的屬性,獲取屬性的值并將其賦值給元素的Java類中定義的相關(guān)變量;算法能夠正確地判斷元素包含的子元素,為子元素創(chuàng)建Java對(duì)象,并將對(duì)象賦值給元素的Java類中定義的相關(guān)變量;算法能夠依據(jù)源文檔中元素之間的嵌套關(guān)系正確地建立Java對(duì)象之間的引用關(guān)系。

5 ?結(jié) ?語
本文提出一種將XML Schema文檔轉(zhuǎn)換為Java代碼的算法,并實(shí)現(xiàn)了該算法。W3C Recommendation發(fā)布的XML Schema最新標(biāo)準(zhǔn)包含30種元素和12種限定元素,算法可以實(shí)現(xiàn)其中28種元素和全部12種元素到Java代碼的轉(zhuǎn)換,并且可以依據(jù)XML Schema文檔中元素之間的嵌套關(guān)系建立Java對(duì)象間的引用關(guān)系。算法從結(jié)構(gòu)上分為解析單元和Java對(duì)象創(chuàng)建單元,實(shí)現(xiàn)包括34個(gè)Java類或接口。選取ATA/AIA/ASD S1000D Issue 4.2標(biāo)準(zhǔn)制定的19個(gè)XML Schema文檔作為實(shí)驗(yàn)文檔對(duì)算法的正確性和有效性進(jìn)行驗(yàn)證。基于該算法設(shè)計(jì)開發(fā)了一個(gè)XML數(shù)據(jù)編輯框架原型,并在IETM制作平臺(tái)中得到初步驗(yàn)證。該算法具有通用性,可以應(yīng)用到其他XML應(yīng)用領(lǐng)域。


參考文獻(xiàn)
[1] 徐宗昌.裝備IETM技術(shù)標(biāo)準(zhǔn)實(shí)施指南[M].北京:國(guó)防工業(yè)出版社,2012.
XU Zongchang. Implementary guide of equipment IETM technical standard [M]. Beijing: National Defense Industry Press, 2012.
[2] 徐宗昌,雷育生.裝備IETM研制工程總論[M].北京:國(guó)防工業(yè)出版社,2012.
XU Zongchang, LEI Yusheng. Generalization of equipment IETM developing engineering [M]. Beijing: National Defense Industry Press, 2012.
[3] 王行哲.XML模式到概念模型的轉(zhuǎn)換方法與工具研究[D].武漢:武漢理工大學(xué),2008.
WANG Xingzhe. Method and tool for transforming XML schema to conceptual model [D]. Wuhan: Wuhan University of Technology, 2008.
[4] W3C Recommendation. W3C XML schema definition language (XSD) 1.1 Part 1: structures [S]. US: W3C Recommendation, 2012.
[5] W3C Recommendation. W3C XML schema definition language (XSD) 1.1 Part 2: datatypes [S]. US: W3C Recommendation, 2012.
[6] MA J L, ZHANG S B, HU T S, et al. Parallel speculative Dom?based XML parser [C]// 2012 IEEE International Conference on High Performance Computing. Liverpool: IEEE, 2012: 33?40.
[7] DESHMUKH V M, BAMNOTE G R. An empirical study of XML parsers across applications [C]// 2015 International Conference on Computing Communication Control & Automation. Pune: IEEE, 2015: 1?7.
[8] W3C. Document object model (DOM) level 1 specification: Version 1.0 [EB/OL]. [1998?10?01]. https://www.w3.org/TR/REC?DOM?Level?1.
[9] PAN Y F, ZHANG Y, CHIU K. Hybrid parallelism for XML SAX parsing [C]// 2008 IEEE International Conference on Web Service. Beijing: IEEE, 2008: 505?512.
[10] S1000D. International specification for technical publications using a common source database [S/OL]. [2016?01?15]. http://public.s1000d.org/Pages/Home.aspx.