李真 孟曉 黃江平
(1.中國軟件評測中心軟件與信息系統(tǒng)測評工程技術(shù)中心,北京 100048;2.中國軟件評測中心軟件與信息系統(tǒng)測評工程技術(shù)中心,北京 100048;3.中國軟件評測中心軟件與信息系統(tǒng)測評工程技術(shù)中心,北京 100048)
隨著標準表示格式的豐富,XML文檔作為系統(tǒng)間數(shù)據(jù)傳輸和數(shù)據(jù)互通的載體,被各行各業(yè)廣泛應(yīng)用于標準制定[1]。XML格式數(shù)據(jù)的高可讀性使其不僅適合用于網(wǎng)絡(luò)中結(jié)構(gòu)化數(shù)據(jù)傳輸,更方便程序員讀寫[2]。
XML文檔校驗中一個很重要的角色是XML Schema。XML Schema主要用于描述XML文檔的結(jié)構(gòu),同時也可用于對XML文檔校驗[3]。一般用戶方提供的Schema可能因描述顆粒度不同,未涵蓋全部業(yè)務(wù)規(guī)則要求。通過編寫代碼可實現(xiàn)最細致的XML Schema,能夠?qū)ML結(jié)構(gòu)和數(shù)據(jù)規(guī)則均進行定義。但代碼實現(xiàn)的Schema不僅非常復雜,而且較為死板,無法達到界面可視化靈活可配。而大部分Schema可能僅僅是框架描述。除此之外,業(yè)務(wù)規(guī)則如節(jié)點或數(shù)據(jù)之間的約束關(guān)系(排他、多選、外鍵等)一般未在Schema中體現(xiàn)。例如,醫(yī)療行業(yè)標準《WS/T 500.32-2016電子病歷共享文檔規(guī)范 第32部分:住院病案首頁》[4]定義診斷記錄章節(jié)基數(shù)為1..1,意為診斷記錄章節(jié)必須存在且只能出現(xiàn)一次,而沒有一個現(xiàn)成工具能對這些約束關(guān)系進行校驗。因此,雖然XML Spy等工具可對XML文檔格式進行校驗,但如果XML Schema本身不是最細致的表達,將導致驗證被測目標是否滿足規(guī)范要求存在覆蓋不全面、數(shù)據(jù)標準需要人工逐一比對驗證等問題[5]。
我們曾開展醫(yī)療行業(yè)標準符合性測試(如《WS 445-2014(所有部分)電子病歷基本數(shù)據(jù)集》和《WS/T 500-2016(所有部分)電子病歷共享文檔規(guī)范》)[4,6,7],具有豐富的測試經(jīng)驗。但曾用于開展測試的工具僅為定制化工具,無法應(yīng)用于所有行業(yè)?;跇I(yè)務(wù)對數(shù)據(jù)格式校驗的需求,我們在此基礎(chǔ)上研究提取各行業(yè)XML標準中所涵蓋通用規(guī)則,設(shè)計開發(fā)一套通用于多行業(yè)的XML解析及數(shù)據(jù)校驗系統(tǒng)。該系統(tǒng)主要實現(xiàn)以下功能:
(1)實現(xiàn)針對不同數(shù)據(jù)標準規(guī)則,對XML文檔中數(shù)據(jù)項進行標準符合性測試。
(2)界面可視化實現(xiàn)標準規(guī)則可定制化、靈活配置。
(3)僅有XML示例模板而無Schema的情況下,可反向生成Schema文件。
該系統(tǒng)是一套滿足校驗各行業(yè)XML文檔結(jié)構(gòu)的解析及數(shù)據(jù)標準校驗系統(tǒng)。該系統(tǒng)方便用戶操作同時可靈活配置,通過配置業(yè)務(wù)規(guī)則即可滿足測試需求。該工具將適用于更多行業(yè),且擁有完全自主知識產(chǎn)權(quán)。
2.1.1 約束條件設(shè)置
某些行業(yè)在制訂標準的同時會編制Schema文件,此時可將Schema文件導入系統(tǒng),通過配置基線(節(jié)點出現(xiàn)的最大值和最小值)實現(xiàn)對文檔中章節(jié)和節(jié)點的循環(huán)設(shè)置?;€對應(yīng)標準約束條件,如醫(yī)療行業(yè)標準《WS/T 500.32-2016電子病歷共享文檔規(guī)范 第32部分:住院病案首頁》定義診斷記錄章節(jié)基數(shù)為1..1。此處基數(shù)即為該章節(jié)約束條件,可通過系統(tǒng)界面化實現(xiàn)基線配置功能,靈活設(shè)置Schema文件約束條件。
2.1.2 生成Schema
通過總結(jié)多種行業(yè)標準,我們發(fā)現(xiàn)并非每個行業(yè)制定XML標準及模板后,均會編寫XML Schema。研究該需求缺口,我們開發(fā)通過導入XML示例模板并進行簡單編輯的方式生成Schema文件功能。提交XML示例模板至系統(tǒng),根據(jù)行業(yè)標準規(guī)定配置XML示例模版相關(guān)約束和條件,可生成相應(yīng)Schema文件,再對XML文檔進行校驗。系統(tǒng)根據(jù)XML示例模版生成的Schema文件將放在項目目錄Schema下,數(shù)據(jù)庫中同時保存該文件完整目錄,如此可針對兩種來源保持一致對外接口。
對于系統(tǒng)中已存在的Schema,可通過關(guān)聯(lián)查看對應(yīng)XML示例模版內(nèi)容,同時選擇Schema名稱也可查看Schema內(nèi)容,即XSD文件內(nèi)容。若各行業(yè)標準因行業(yè)發(fā)展產(chǎn)生版本變更,則可根據(jù)標準版本變動情況對Schema進行修改。
2.2.1 數(shù)據(jù)規(guī)則靈活可配置
數(shù)據(jù)元規(guī)則表達式的解析和對數(shù)據(jù)的校驗計算均來自行業(yè)擴展規(guī)則,此時涉及兩方面問題,一個是解析,另一個是計算。
規(guī)則解析是為了將一個完整的規(guī)則表達式轉(zhuǎn)換成其最小子規(guī)則,也就是系統(tǒng)只需實現(xiàn)每一個最小子規(guī)則動態(tài)可配置,即可實現(xiàn)完整規(guī)則表達式動態(tài)可配置。根據(jù)對醫(yī)療、水利、交通等行業(yè)的規(guī)則分析,最小子規(guī)則主要包含兩部分內(nèi)容:數(shù)據(jù)格式和數(shù)據(jù)長度。實現(xiàn)方式如下。
數(shù)據(jù)格式一般可通過正則表達式實現(xiàn)。
數(shù)據(jù)長度是計算后的結(jié)果。計算過程將涉及輸入、計算函數(shù)和輸出。輸出是我們需要的結(jié)果,輸入是該數(shù)據(jù)元配置XPath所指定的元素值,因此需給每個最小子規(guī)則配置計算函數(shù)并能動態(tài)執(zhí)行即可實現(xiàn)規(guī)則的靈活可配置。
動態(tài)計算引擎一般和規(guī)則引擎技術(shù)關(guān)聯(lián)起來,因此系統(tǒng)引入Aviator規(guī)則引擎。如一個簡單的固定長度驗證表達式:string.length(s) == long(s1),Aviator可動態(tài)轉(zhuǎn)換上述表達式進行計算,返回計算結(jié)果,這里s和s1為傳入?yún)?shù),剩下的問題為如何獲取參數(shù)。以AN3為例,s參數(shù)為該數(shù)據(jù)元XPath所定位的元素值,s1參數(shù)為“3”,因此實現(xiàn)獲取3這個值即可。這里同樣采用正則表達式來實現(xiàn),以該表達式為例,提取3這個值的正則表達式為^AN((?=[^a-zA-Z])|(?=$)),同樣正則表達式也可配置可動態(tài)修改,因此在規(guī)則部分即可實現(xiàn)靈活可配置。
2.2.2 數(shù)據(jù)規(guī)則執(zhí)行
最小子規(guī)則實現(xiàn)靈活可配置,余下工作就是組合各個最小子規(guī)則。
這里引入鏈表的概念,一個規(guī)則表達式會被解析為多個最小子規(guī)則節(jié)點,這些節(jié)點首先按優(yōu)先級高低排序并按順序執(zhí)行,同時每個節(jié)點有一個next標志位,next為true則代表本節(jié)點執(zhí)行完成后可繼續(xù)執(zhí)行下一節(jié)點,next為false則代表本節(jié)點執(zhí)行完成后結(jié)束整個校驗流程。
測試執(zhí)行流程圖如圖1所示。
圖1 測試執(zhí)行流程圖
2.2.3 獲取數(shù)據(jù)元值
數(shù)據(jù)元中的規(guī)則表達式可動態(tài)解析和執(zhí)行,值域有自己的配置表保存和查詢,因此,目前最主要問題為如何將數(shù)據(jù)從XML文檔中取出。XML文檔中數(shù)據(jù)定位一般使用XPath定位和查詢元素,它是一門在XML文檔中查找信息的語言,擁有自己的語法。因此為數(shù)據(jù)元配置XPath即可。
具體過程如下:
將數(shù)據(jù)元配置XPath路徑(這里設(shè)計為可以有多個XPath,同一元素可能在不同結(jié)構(gòu)體中);
根據(jù)XPath將XML文檔節(jié)點Node取出;
獲取Node的Text,該Text即為要獲取的數(shù)據(jù);
分別對Text數(shù)據(jù)進行規(guī)則校驗和值域校驗。
XML解析及數(shù)據(jù)校驗系統(tǒng)技術(shù)架構(gòu)如圖2所示,系統(tǒng)分為基礎(chǔ)層、支撐層、應(yīng)用層、展示層和用戶層。
圖2 系統(tǒng)技術(shù)架構(gòu)
(1)基礎(chǔ)層包括.NET、JDK和數(shù)據(jù)庫等基礎(chǔ)結(jié)構(gòu)。主要實現(xiàn)底層數(shù)據(jù)庫邏輯。
(2)支撐層包括Service層和DAO層。
DAO層可直接操作數(shù)據(jù)庫代碼,該層僅負責使對應(yīng)每個表完成增刪改查。DAO層同樣需先創(chuàng)建DAO接口,再在配置文件中定義該接口的實現(xiàn)類,配置數(shù)據(jù)源和數(shù)據(jù)庫連接參數(shù)。該層主要負責數(shù)據(jù)持久化存儲。
Service層負責管理具體功能實現(xiàn),因此該層主要為一些實現(xiàn)具體業(yè)務(wù)功能類,稱為Business類。Controller層可以調(diào)用該層接口,處理業(yè)務(wù)邏輯應(yīng)用。Service層負責處理Controller層傳遞過來的數(shù)據(jù),再將處理后數(shù)據(jù)傳給DAO層,用于鏈接數(shù)據(jù)庫,方便DAO層進行增刪改查。同時,Service層負責處理DAO層傳遞過來的數(shù)據(jù),將其進行封裝,如封裝成JavaBean。系統(tǒng)主要業(yè)務(wù)邏輯也在該層進行實現(xiàn),我們改為先設(shè)計接口,再創(chuàng)建需要實現(xiàn)的類,然后在配置文件中配置實現(xiàn)的關(guān)聯(lián)。這樣封裝好Service層業(yè)務(wù)邏輯并進一步劃分,便于業(yè)務(wù)邏輯的獨立和可再現(xiàn),增加該層可維護性。
支撐層實現(xiàn)基礎(chǔ)配置及管理功能,包括數(shù)據(jù)元管理、XML模板管理、規(guī)則管理、值域管理和XML解析模塊等。
(3)應(yīng)用層為Controller層,即為控制器,負責管理業(yè)務(wù)調(diào)度和管理跳轉(zhuǎn)。主要通過獲取數(shù)據(jù)后調(diào)用Service層接口,包括Service層的處理業(yè)務(wù)邏輯,然后返回數(shù)據(jù)來實現(xiàn)控制具體流程的功能。如具體業(yè)務(wù)功能由何種類來實現(xiàn),實現(xiàn)結(jié)果通過何種途徑顯示等,均由Controller層決定。同時Controller層需負責與展示層和Service層的通信,通信過程需借助一些Bean類進行信息傳遞。從控制層功能上來說,因為該系統(tǒng)業(yè)務(wù)邏輯并不復雜,所以該層代碼編寫并未如其他復雜業(yè)務(wù)邏輯的系統(tǒng)繁重和復雜。
應(yīng)用層主要實現(xiàn)具體測試功能。
(4)展示層是與客戶的交互層,主要接收用戶提交的請求,將用戶提交請求和數(shù)據(jù)傳遞給下一層,并將后臺響應(yīng)結(jié)果返回給客戶層。
展示層為系統(tǒng)的展示界面。
本系統(tǒng)采用基于C/S模式開發(fā),有如下特點。
1)服務(wù)端基于Java的Springboot框架開發(fā),創(chuàng)建獨立的Spring應(yīng)用程序,并且直接嵌入Tomcat,無需其他配置,主要負責業(yè)務(wù)邏輯處理。服務(wù)端優(yōu)點是僅僅依賴JDK運行環(huán)境,不受外部操作系統(tǒng)環(huán)境影響,一次編譯,多處運行。
2)客戶端基于Electron框架開發(fā),主要負責界面展示、控制服務(wù)端后臺進程啟停,優(yōu)點是Electron打包之后的客戶端本身就是一個瀏覽器,屏蔽客戶機器由于使用不同瀏覽器而產(chǎn)生的兼容問題,同時還支持一鍵安裝,部署過程和安裝客戶端軟件同樣便宜。
3)數(shù)據(jù)庫H2,相比其他數(shù)據(jù)庫系統(tǒng),H2數(shù)據(jù)庫輕便,僅有一個jar文件,無需安裝,同時還可嵌入服務(wù)端一起打包發(fā)布,方便存儲系統(tǒng)產(chǎn)生的結(jié)構(gòu)化數(shù)據(jù),隨著Java服務(wù)端啟動而啟動,和服務(wù)端共用一個JVM內(nèi)存空間。
XML文檔校驗完整測試流程如圖3所示,此處以提交醫(yī)療行業(yè)互聯(lián)互通測評電子病歷共享文檔(電子病歷共享文檔規(guī)范 第2部分:門(急)診病歷)為例。
圖3 XML文檔校驗測試流程圖
首先,需提交XML文檔到XML解析及數(shù)據(jù)校驗系統(tǒng),在此需要說明的是XML文檔結(jié)構(gòu)必須符合XML格式,若不符合基本XML格式,將無法進入后續(xù)校驗流程。
系統(tǒng)采用 Schema 對文檔結(jié)構(gòu)進行標準化校驗,驗證XML文檔結(jié)構(gòu)是否符合標準規(guī)定。在系統(tǒng)對一批XML文檔進行Schema結(jié)構(gòu)校驗時,要求必須將每一個XML文檔均指定對應(yīng)的Schema文件,即需要基于Schema對XML文檔進行分類校驗。系統(tǒng)針對XML文檔分類進行自動化處理,有如下兩種情況:
(1)XML文檔頭標簽存在Location屬性,可根據(jù)Location名稱,自動匹配Schema文件。
(2)XML文檔頭標簽不存在Location屬性,則自動分類失敗,此時需要將該類文件手動指定一個Schema文件或引入新Schema文件,則該分類下所有XML文檔均會自動歸類到該Schema分類下。
具體流程如下:
(1)在系統(tǒng)中導入/提交門(急)診病歷.xml文檔。
(2)點擊下一步,進行Schema文件的選擇。
(3)系統(tǒng)對提交的XML文檔自動匹配相同種類Schema文件,即門(急)診病歷Schema文件。
(4)若此時自動匹配Schema文件名稱有誤,則需要選擇系統(tǒng)中與該XML文檔種類相同的Schema文件,進行手動分類。
(5)點擊測試執(zhí)行,系統(tǒng)會對提交的門(急)診病歷.xml文檔進行測試,對文檔中數(shù)據(jù)源進行校驗。
(6)執(zhí)行結(jié)束后,系統(tǒng)會返回執(zhí)行結(jié)果,并提供導出結(jié)果功能。