亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

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

        2021-03-09 01:34:52王宏明林衛(wèi)永王泉榮溫業(yè)中
        關(guān)鍵詞:定義

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

        (通號(hào)萬(wàn)全信號(hào)設(shè)備有限公司,杭州 310000)

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

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

        1 XML文檔分析

        以有軌電車的軟件領(lǐng)域經(jīng)常用到的XML 配置文件為例來(lái)進(jìn)行說(shuō)明。

        對(duì)于該文檔,可以得到一個(gè)XML 模式定義D,按照文獻(xiàn)[4]的五元組定義進(jìn)行分析,可以得到文檔樹,如圖1 所示。

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

        對(duì)示例文檔對(duì)象分析,可知,該文檔需要3 個(gè)C++類進(jìn)行對(duì)應(yīng)。使用UML 圖來(lái)表示3 個(gè)類及關(guān)系,如圖2 所示。

        圖2 UML類圖Fig.2 UML class diagram

        2 C++及QT結(jié)合的動(dòng)態(tài)生成對(duì)象原理

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

        1)動(dòng)態(tài)生成一個(gè)類對(duì)象實(shí)例

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

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

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

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

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

        2)動(dòng)態(tài)設(shè)置類屬性的值

        C++有運(yùn)行時(shí)類型信息RTTI(Run-Time Type Identif ication),但是該信息只能用來(lái)鑒別類型,無(wú)法操作類的成員變量。

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

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

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

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

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

        3 算法設(shè)計(jì)

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

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

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

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

        3)如果是復(fù)合屬性,那么根據(jù)前述的createInstance 方法,按照子節(jié)點(diǎn)名,動(dòng)態(tài)生成一個(gè)對(duì)應(yīng)的對(duì)象實(shí)例。

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

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

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

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

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

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

        4 算法實(shí)現(xiàn)

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

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

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

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

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

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

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

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

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

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

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

        圖5 UML類關(guān)系圖Fig.5 UML class relationship diagram

        示例代碼如圖6 所示。

        圖6 示例代碼Fig.6 Sample code

        運(yùn)行結(jié)果如圖7 所示。

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

        5 結(jié)語(yǔ)

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

        圖7 示例代碼運(yùn)行結(jié)果Fig.7 Operation result of sample code

        猜你喜歡
        定義
        以愛之名,定義成長(zhǎng)
        活用定義巧解統(tǒng)計(jì)概率解答題
        例談橢圓的定義及其應(yīng)用
        題在書外 根在書中——圓錐曲線第三定義在教材和高考中的滲透
        永遠(yuǎn)不要用“起點(diǎn)”定義自己
        海峽姐妹(2020年9期)2021-01-04 01:35:44
        嚴(yán)昊:不定義終點(diǎn) 一直在路上
        定義“風(fēng)格”
        成功的定義
        山東青年(2016年1期)2016-02-28 14:25:25
        有壹手——重新定義快修連鎖
        修辭學(xué)的重大定義
        处破痛哭a√18成年片免费| 国产一区二区三区内射| 精品九九人人做人人爱| 欧美成a人片在线观看久| 精品一区二区三区久久久| 亚洲二区精品婷婷久久精品| 西川结衣中文字幕在线| 欧美一区二区三区激情| 制服丝袜视频国产一区| 韩国女主播一区二区三区在线观看 | 99这里只有精品| 国产喷白浆精品一区二区| 日本一区二区三区视频免费在线 | 亚洲捆绑女优一区二区三区| 精品国产综合区久久久久久 | 吃奶摸下高潮60分钟免费视频| 午夜亚洲av永久无码精品| 日本a级大片免费观看| 大香蕉视频在线青青草| 无码h黄肉3d动漫在线观看| 国产精品卡一卡二卡三| 91精品国产无码在线观看| 国产专区国产精品国产三级| 国产aⅴ无码专区亚洲av麻豆| 中文字幕免费观看视频| 日韩精品一区二区三区含羞含羞草| 日本中文一区二区在线观看| 中文字幕人妻熟女人妻洋洋| 久久这里都是精品一区| 丝袜美腿制服诱惑一区二区| 亚洲乱亚洲乱妇| 九九99久久精品在免费线18| 久久亚洲精品成人av观看| 免费a级毛片无码a∨蜜芽试看| 一区二区传媒有限公司 | 久久天天躁夜夜躁狠狠躁2022| 丝袜美腿一区二区在线观看 | 日本一二三区在线不卡| 高潮内射双龙视频| 精品人妻少妇一区二区不卡| 亚洲国产av中文字幕|