999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于QT的XML文件自動轉(zhuǎn)換方法

2021-03-09 01:34:52王宏明林衛(wèi)永王泉榮溫業(yè)中
鐵路通信信號工程技術 2021年2期
關鍵詞:定義

王宏明,林衛(wèi)永,王泉榮,溫業(yè)中

(通號萬全信號設備有限公司,杭州 310000)

XML 是一種廣泛使用的具有結構性和自描述性的標記語言,在有軌電車領域的工程建模、配置文件、數(shù)據(jù)交換等功能上常被使用。由于軌道交通領域的安全、效率等要求,C/C++語言常當做實現(xiàn)語言。但是由于C++語言缺少java、C#等高級語言的反射特性,將XML 文件讀取到系統(tǒng)內(nèi)部,轉(zhuǎn)換為計算機能夠理解的對象時,沒有自動轉(zhuǎn)換的方法,實現(xiàn)比較繁瑣,代碼中充斥著if、else 等判斷,代碼的可維護性、可擴展性都比較差。在將C++對象寫入到XML 文件時,也需要通過定義一大堆的字符串來寫到XML 文件中,代碼的可維護性,可擴展性都不夠好。文獻[1]通過Java 來實現(xiàn)了XML到編程語言的轉(zhuǎn)換,將XML 元素對應到定義好的Java 類中,但是對于如何具體實現(xiàn)XML 節(jié)點到Java 屬性的載入沒有涉及。文獻[2]對于XML 和數(shù)據(jù)庫的對象模型的轉(zhuǎn)換數(shù)學算法進行了闡述,也沒有對如何實現(xiàn)該機制進行詳細的描述。文獻[3]對于如何將一個定義好的結構體輸出到XML 文件中進行研究,但是缺少通用性。

本文提出一種基于QT 的XML 文件自動轉(zhuǎn)換的方法,只需要定義好類的數(shù)據(jù)結構,就能夠自動的將符合要求的XML 載入進來,同時也能將C++對象按照數(shù)據(jù)結構定義,以XML 格式保存。

1 XML文檔分析

以有軌電車的軟件領域經(jīng)常用到的XML 配置文件為例來進行說明。

對于該文檔,可以得到一個XML 模式定義D,按照文獻[4]的五元組定義進行分析,可以得到文檔樹,如圖1 所示。

圖1 XML文檔樹Fig.1 XML file tree

對示例文檔對象分析,可知,該文檔需要3 個C++類進行對應。使用UML 圖來表示3 個類及關系,如圖2 所示。

圖2 UML類圖Fig.2 UML class diagram

2 C++及QT結合的動態(tài)生成對象原理

對于XML 文檔與C++類之間,已經(jīng)得到對應的邏輯關系。但是在C++語言上,還需要解決下面2 個問題。

1)動態(tài)生成一個類對象實例

C++本身沒有根據(jù)名字生成類對象實例的功能。想要在讀取XML 的parameters 節(jié)點時生成QParameters 的實例,可以用C++的模板功能來模擬實現(xiàn)動態(tài)生成類對象實例的功能。示例代碼如下:

通過createInstance()的方式,可以生成QParameters 類的對象實例。

為了能夠讓C++程序能夠通過名字查詢到該函數(shù),然后調(diào)用,還需要定義個函數(shù)指針類型。

typedef QObject* (*createInstance_func)(QObject* parent );

然后通過哈希表QHast的形式,就可以通過名字得到對象實例。

2)動態(tài)設置類屬性的值

C++有運行時類型信息RTTI(Run-Time Type Identif ication),但是該信息只能用來鑒別類型,無法操作類的成員變量。

C++類本身沒有屬性,只有類成員變量及類成員函數(shù),不提供動態(tài)設置成員變量的功能。但是QT 提供了一套元對象系統(tǒng)(Meta-Object System),可以幫助實現(xiàn)該功能。

首先要基于QT 的元對象系統(tǒng)來賦予C++類屬性的功能。通過在類中使用以下定義:

Q_PROPE RT Y(int carl ength READ getCarlength WRITE getCarlength)

可以賦予C++類屬性。示例中的carLength就是屬性名。

有了屬性以后,把這個XML 節(jié)點的值48 賦予屬性carlength,其實現(xiàn)方式為調(diào)用QObject::setProperty 方法。

3 算法設計

XML 文檔的解析,主要有兩種方式,一種文檔對象模型DOM(Document Object Model),使用樹形結構來描述XML 文檔,層次結構清晰,較為符合人類的抽象認知,在處理過程中會將整個文檔的內(nèi)容都載入到內(nèi)存中,內(nèi)存占用率較高。另外一種是流式解析的SAX(simple API for XML),相比于DOM,SAX 的速度更快,效率更高,但它是逐行掃描,邊掃描邊解析,操作復雜。為便于說明,后面使用DOM 的方式來說明。

XML 文檔的內(nèi)容如圖1 所示,configuration為根節(jié)點,parameters 和database 作為其子節(jié)點。對于每一個子節(jié)點,進行如圖3 所示的處理。

1)根據(jù)傳入的DOM 節(jié)點,判斷是否有子節(jié)點。有子節(jié)點則認為是復合屬性,否則為簡單屬性。

2)如果為簡單屬性,則提取子節(jié)點的內(nèi)容,賦值給對象實例。然后繼續(xù)處理下一子節(jié)點。

3)如果是復合屬性,那么根據(jù)前述的createInstance 方法,按照子節(jié)點名,動態(tài)生成一個對應的對象實例。

4)對3)生成的對象實例進行內(nèi)容組裝。

圖3 子節(jié)點處理流程Fig.3 Child node processing flow

5)判斷當前子節(jié)點的屬性名是否記錄在List類型的信息中,如果是List 類型的,則按照List屬性的方法來組裝。

6)如果不是List 類型的屬性,則將該對象實例的值賦予父實例對象。

通過以上步驟,可以通過遞歸的方式,高效得將XML 文件內(nèi)容轉(zhuǎn)換為C++的對象實例。

將C++對象實例轉(zhuǎn)換XML 形式輸出相對比較簡單,只需要遍歷C++類的所有屬性,然后組成XML 節(jié)點即可,在此不再贅述。

4 算法實現(xiàn)

依據(jù)動態(tài)對象生成原理和算法設計,實現(xiàn)部分主要分為兩部分:動態(tài)對象生成的實現(xiàn)和對象實例組裝的實現(xiàn)。

動態(tài)對象生成模塊使用一個泛型類DynamicObjectFactory。 該 類 主 要 就 是 構建對象生成原理中的哈希表QHash

由于QT 中只有QObject 的派生類才能使用屬性,所以要求的XML 相關的類需要從QObject 派生。通過此方法將類名字和創(chuàng)建對象實例的方法注冊保存,以便后續(xù)使用。

對象實例的組裝模塊,定義了一個基類XmlBaseData,由基類來實現(xiàn)XML 轉(zhuǎn)換的工作,那么以后使用時,只需要定義XML 節(jié)點對應的數(shù)據(jù)結構的類,即可將XML 轉(zhuǎn)換為C++的對象實例。

XmlBaseData 的類結構如圖4 所示。內(nèi)部有兩個靜態(tài)的成員變量,分別記錄List 類型的屬性和復合屬性,以便組裝實例的時候名字的查找。

圖4 XMLBaseData的UML類圖Fig.4 UML class diagram of XMLBaseData

load 函數(shù)用于將XML 的內(nèi)容組裝到C++對象實例中,write 則將對象實例以XML 的方式寫出到文件中。

preload 函數(shù)則是為了一些特殊的節(jié)點或類型預留,為一個返回0 的空函數(shù)。在派生類需要對某些節(jié)點進行特殊處理預留。

registerAllProp 函數(shù)是需要在派生類的構造函數(shù)中調(diào)用1 次的函數(shù),即所有該類的實例只需要進行1 次處理的函數(shù)。該函數(shù)的作用是遍歷當前類的所有屬性,將所有的復合屬性保存到complexProps 哈希表中,以便于后續(xù)的處理。

以本文中的示例XML 文檔為例,需要創(chuàng)建如下的類,類關系如圖5 所示。

3 個XML相關的類QConfiguration、QParameters、QDatabase 都從XmlBaseData 基類派生,本身不需要特別定義方法,只需定義數(shù)據(jù)的屬性即可。在使用時,只需調(diào)用基類的load 函數(shù)即可將XML 文件內(nèi)容讀入。

圖5 UML類關系圖Fig.5 UML class relationship diagram

示例代碼如圖6 所示。

圖6 示例代碼Fig.6 Sample code

運行結果如圖7 所示。

只需定義好數(shù)據(jù)結構的成員,通過短短3 ~5行代碼就可以完成XML 讀取的工作。

5 結語

提出一種將XML 文檔和C++對象實例的互相轉(zhuǎn)換方法,并實現(xiàn)了該方法。該方法能夠讓開發(fā)人員關注于數(shù)據(jù)和業(yè)務,從繁瑣的字符串比較,一大堆的if-else 組合中解放出來,使用較少的代碼高效地實現(xiàn)了從XML 文件到C++對象實例的轉(zhuǎn)換,具有通用性,同時也為特殊需要提供了接口預留。該方法使用了基于QT 的實現(xiàn)方式,由于QT 是跨平臺的架構,所以該方法可以在windows 和Linux上跨平臺使用。

圖7 示例代碼運行結果Fig.7 Operation result of sample code

猜你喜歡
定義
以愛之名,定義成長
活用定義巧解統(tǒng)計概率解答題
例談橢圓的定義及其應用
題在書外 根在書中——圓錐曲線第三定義在教材和高考中的滲透
永遠不要用“起點”定義自己
海峽姐妹(2020年9期)2021-01-04 01:35:44
嚴昊:不定義終點 一直在路上
華人時刊(2020年13期)2020-09-25 08:21:32
定義“風格”
成功的定義
山東青年(2016年1期)2016-02-28 14:25:25
有壹手——重新定義快修連鎖
修辭學的重大定義
當代修辭學(2014年3期)2014-01-21 02:30:44
主站蜘蛛池模板: 91免费观看视频| 亚洲第一区精品日韩在线播放| 试看120秒男女啪啪免费| 欧美视频免费一区二区三区 | 中文字幕乱妇无码AV在线| 国产高清在线丝袜精品一区| 免费观看三级毛片| 午夜毛片福利| 亚洲一区二区三区国产精品| 99久久精品免费看国产电影| 99ri精品视频在线观看播放| 久热re国产手机在线观看| 在线精品欧美日韩| 欧美精品另类| 黄色网站不卡无码| 在线观看免费人成视频色快速| 中文字幕在线不卡视频| 91精品国产自产91精品资源| 色综合天天综合| 亚洲精品午夜天堂网页| 麻豆精品在线播放| 国产不卡在线看| 亚洲综合狠狠| 在线99视频| 不卡无码h在线观看| 视频一区亚洲| 波多野衣结在线精品二区| 国产专区综合另类日韩一区| 国模在线视频一区二区三区| 久久国产热| 全部免费特黄特色大片视频| 国产成人综合久久| 亚洲午夜福利精品无码不卡| 亚洲色图欧美在线| 久久久精品无码一二三区| 亚洲一级毛片在线观| 国产亚洲欧美在线视频| 亚洲国产精品无码久久一线| 青青青视频91在线 | 日韩视频免费| 色婷婷狠狠干| 成人综合久久综合| 精品亚洲国产成人AV| 久久黄色视频影| 免费激情网址| 日韩欧美成人高清在线观看| 亚洲欧美一区二区三区麻豆| 国产乱视频网站| 国产一级妓女av网站| 亚洲IV视频免费在线光看| 亚洲成人播放| 亚洲国产成人超福利久久精品| 狠狠亚洲婷婷综合色香| 在线精品欧美日韩| 国产91精品调教在线播放| www.91在线播放| 久久香蕉欧美精品| 欧美97色| 久久影院一区二区h| 国产欧美日韩专区发布| 亚洲一区二区三区中文字幕5566| 国产成人精品一区二区三在线观看| 成人精品午夜福利在线播放| 国产在线日本| 2024av在线无码中文最新| 超碰精品无码一区二区| 国产午夜无码片在线观看网站| 久一在线视频| 中国黄色一级视频| 国产成人高清精品免费| 91成人精品视频| 久久久精品无码一区二区三区| 在线亚洲小视频| 亚洲av无码片一区二区三区| 久久国产亚洲偷自| 国产三级国产精品国产普男人| 婷婷激情五月网| 国精品91人妻无码一区二区三区| 无遮挡一级毛片呦女视频| 亚洲欧美综合另类图片小说区| 日韩AV无码免费一二三区| 特级精品毛片免费观看|