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