why:接到需求把設備端的xml參數,轉換爲ini,做一箇中間的數據結構,中轉後,格式化保存爲ini格式。c#寫好了,但另外一個程序是qt寫的
目錄:
一 c#和QT在xml操作的差異差異
二實例解析的xml
三c# 遞歸轉換XML配置參數代碼
四 QT遞歸轉換XML配置參數代碼
五 QT下xml轉ini的代碼
1 接口名變更,函數的首字母大小寫 C#是( CreateElement) vs QT (createElement)
2 成員自動引用和QT的指針傳遞xml成員節點
3 屬性的獲取方式差異
C# 映射表獲取 (keyChild.Attributes["type"].Value) vs QT 接口獲取 ( keyChild.attribute("type").trimmed();) //屬性值的獲取<VALUE type="ENUM">1</VALUE>,如其中的type屬性
c# keyChild.InnerText vs QT keyChild.text().trimmed(); //節點文本的獲取<VALUE type="ENUM">1</VALUE>,如其中的“1”
c# child.Name vs QT child.tagName() //標誌的獲取<VALUE type="ENUM">1</VALUE>,如其中的VALUE
4 對象名比較
XmlDocument vs QDomDocument
XmlNode vs QDomNode
XmlElement vs QDomElement
5 編碼轉換是公有的問題。是gbk 還是 utf-8
二實例解析的xml
<?xml version="1.0" encoding="gb2312" standalone="yes" ?>
<HvParamDoc version="1.0">
<HvParam>
<SECTION name="System" cname="系統">
<KEY name="LogLevel">
<VALUE type="ENUM">1</VALUE>
<CHNAME type="STR">日誌輸出等級</CHNAME>
<COMMENT type="STR">日誌輸出等級</COMMENT>
<DEFAULT type="INT">1</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">3</MAX>
<RANK type="INT">3</RANK>
<ENUM type="STR">0:錯誤等級;1:常規等級;2:操作等級;3:調試等級</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="CommDevNo">
<VALUE type="STR">ITTS-A16-LS15020124</VALUE>
<CHNAME type="STR">設備編號</CHNAME>
<COMMENT type="STR">設備序列號</COMMENT>
<DEFAULT type="STR">DevNo-HV</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">1</ONLYREAD>
</KEY>
<KEY name="Co4mmDevName">
<VALUE type="STR">未命名</VALUE>
<CHNAME type="STR">設備名稱</CHNAME>
<COMMENT type="STR">設備名稱</COMMENT>
<DEFAULT type="STR">未命名</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<SECTION name="Build" cname="編譯">
<KEY name="Firmware No.">
<VALUE type="STR">rootfs:V14;kernel:Linux 3.17.1+ #2 SMP Mon Dec 29 13:42:46 CST 2014</VALUE>
<CHNAME type="STR">固件版本號</CHNAME>
<DEFAULT type="STR">rootfs:V14;kernel:Linux 3.17.1+ #2 SMP Mon Dec 29 13:42:46 CST 2014</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">1</ONLYREAD>
</KEY>
<KEY name="No.">
<VALUE type="STR">4.1.100.315+2015102811</VALUE>
<CHNAME type="STR">軟件版本號</CHNAME>
<DEFAULT type="STR">4.1.100.315+2015102811</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">1</ONLYREAD>
</KEY>
</SECTION>
<SECTION name="TcpipCfg" cname="網絡配置">
<KEY name="CommIPAddr">
<VALUE type="STR">172.18.251.124</VALUE>
<CHNAME type="STR">IP地址</CHNAME>
<COMMENT type="STR">Wan口的IP地址</COMMENT>
<DEFAULT type="STR">192.168.1.101</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">1</ONLYREAD>
</KEY>
<KEY name="CommMask">
<VALUE type="STR">255.255.0.0</VALUE>
<CHNAME type="STR">子網掩碼</CHNAME>
<COMMENT type="STR">Wan口的子網掩碼</COMMENT>
<DEFAULT type="STR">255.255.255.0</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">1</ONLYREAD>
</KEY>
<KEY name="CommGateway">
<VALUE type="STR">172.18.3.250</VALUE>
<CHNAME type="STR">網關</CHNAME>
<COMMENT type="STR">Wan口的網關</COMMENT>
<DEFAULT type="STR">192.168.1.250</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">1</ONLYREAD>
</KEY>
<KEY name="CommMac">
<VALUE type="STR">4c:02:89:0e:da:f7</VALUE>
<CHNAME type="STR">MAC地址</CHNAME>
<DEFAULT type="STR">4c:02:89:0e:da:f7</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">1</ONLYREAD>
</KEY>
<KEY name="CommLanIPAddr">
<VALUE type="STR">100.100.100.200</VALUE>
<CHNAME type="STR">Lan口IP地址</CHNAME>
<COMMENT type="STR">Lan口的IP地址</COMMENT>
<DEFAULT type="STR">192.168.1.101</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">1</ONLYREAD>
</KEY>
<KEY name="CommLanMask">
<VALUE type="STR">255.255.255.0</VALUE>
<CHNAME type="STR">Lan口子網掩碼</CHNAME>
<COMMENT type="STR">Lan口的子網掩碼</COMMENT>
<DEFAULT type="STR">255.255.255.0</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">1</ONLYREAD>
</KEY>
<KEY name="CommLanGateway">
<VALUE type="STR">100.100.100.250</VALUE>
<CHNAME type="STR">Lan口網關</CHNAME>
<COMMENT type="STR">Wan口的網關</COMMENT>
<DEFAULT type="STR">192.168.1.250</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">1</ONLYREAD>
</KEY>
<KEY name="CommLanMac">
<VALUE type="STR">4c:02:89:0e:da:f8</VALUE>
<CHNAME type="STR">Lan口MAC地址</CHNAME>
<DEFAULT type="STR">4c:02:89:0e:da:f8</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">1</ONLYREAD>
</KEY>
</SECTION>
<SECTION name="TimeCfg" cname="NTP配置">
<KEY name="EnableNTP">
<VALUE type="ENUM">0</VALUE>
<CHNAME type="STR">NTP使能開關</CHNAME>
<COMMENT type="STR">0:不使能;1:使能</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:不使能;1:使能</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="NTPSyncInterval">
<VALUE type="INT">3600</VALUE>
<CHNAME type="STR">NTP時間同步間隔(秒)</CHNAME>
<DEFAULT type="INT">3600</DEFAULT>
<MIN type="INT">300</MIN>
<MAX type="INT">2147483647</MAX>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="NTPServerIP">
<VALUE type="STR">202.120.2.101</VALUE>
<CHNAME type="STR">NTP服務器</CHNAME>
<COMMENT type="STR">NTP服務器IP地址</COMMENT>
<DEFAULT type="STR">202.120.2.101</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="TimeZone">
<VALUE type="ENUM">20</VALUE>
<CHNAME type="STR">時區</CHNAME>
<COMMENT type="STR">系統時區</COMMENT>
<DEFAULT type="INT">20</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">24</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:UTC-12 埃尼威托克島,誇賈林環礁;1:UTC-11 中途島,薩摩亞;2:UTC-10 夏威夷;3:UTC-09 阿拉斯加;4:UTC-08 太平洋時間(美國和加拿大);5:UTC-07 山地時間(美國和加拿大),亞利桑那;6:UTC-06 中部時間(美國和加拿大);7:UTC-05 東部時間(美國和加拿大),印地安那州(東部),波哥大,利馬,基多;8:UTC-04 大西洋時間(加拿大),加拉加斯,拉巴斯;9:UTC-03 巴西利亞,布宜諾斯艾利斯;10:UTC-02 協調世界時-02;11:UTC-01 亞速爾羣島,佛得角羣島;12:UTC+00 協調世界時,都柏林,愛丁堡,倫敦,里斯本,蒙羅維亞,卡薩布蘭卡;13:UTC+01 柏林,斯德哥爾摩,羅馬,伯爾尼,布魯塞爾,維也納,巴黎,馬德里,阿姆斯特丹,布拉格,華沙,布達佩斯;14:UTC+02 雅典,赫爾辛基,伊斯坦布爾,開羅,東歐,哈拉雷,比勒陀利亞,以色列;15:UTC+03 巴格達,科威特,內羅畢,利雅得,莫斯科,聖彼得堡,喀山,伏爾加格勒;16:UTC+04 阿布扎比,馬斯喀特,第比利斯;17:UTC+05 伊斯蘭堡,卡拉奇,葉卡捷琳堡,塔什干;18:UTC+06 阿拉木圖,達卡;19:UTC+07 曼谷,雅加達,河內;20:UTC+08 北京,重慶,烏魯木齊,香港,臺北,珀斯,新加坡;21:UTC+09 東京,大阪,札幌,首爾,雅庫茨克;22:UTC+10 布里斯班,墨爾本,悉尼,關島,莫爾茲比港,海參崴,霍巴特;23:UTC+11 馬加丹,所羅門羣島,新喀里多尼亞;24:UTC+12 斐濟,堪察加半島,馬紹爾羣島,惠靈頓,奧克蘭</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
</SECTION>
</SECTION>
<KEY name="EnableFTP">
<VALUE type="ENUM">0</VALUE>
<CHNAME type="STR">FTP使能開關</CHNAME>
<COMMENT type="STR">0:不使能;1:使能</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:不使能;1:使能</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPServerIP">
<VALUE type="STR">172.18.11.67</VALUE>
<CHNAME type="STR">FTP服務器</CHNAME>
<COMMENT type="STR">FTP服務器IP地址</COMMENT>
<DEFAULT type="STR">172.18.11.67</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPUserName">
<VALUE type="STR">anonymous</VALUE>
<CHNAME type="STR">用戶名</CHNAME>
<COMMENT type="STR">用戶名</COMMENT>
<DEFAULT type="STR">anonymous</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPUserPasswd">
<VALUE type="STR">yetpasswd</VALUE>
<CHNAME type="STR">密碼</CHNAME>
<COMMENT type="STR">密碼</COMMENT>
<DEFAULT type="STR">yetpasswd</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPPort">
<VALUE type="INT">21</VALUE>
<CHNAME type="STR">端口號</CHNAME>
<COMMENT type="STR">端口號</COMMENT>
<DEFAULT type="INT">21</DEFAULT>
<MIN type="INT">1</MIN>
<MAX type="INT">65536</MAX>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPMode">
<VALUE type="ENUM">0</VALUE>
<CHNAME type="STR">FTP模式</CHNAME>
<COMMENT type="STR">0:被動模式;1:主動模式</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:被動模式;1:主動模式</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPChannel1">
<VALUE type="ENUM">0</VALUE>
<CHNAME type="STR">傳輸通道</CHNAME>
<COMMENT type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPChannel2">
<VALUE type="ENUM">0</VALUE>
<CHNAME type="STR">傳輸通道</CHNAME>
<COMMENT type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPChannel3">
<VALUE type="ENUM">0</VALUE>
<CHNAME type="STR">傳輸通道</CHNAME>
<COMMENT type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPChannel4">
<VALUE type="ENUM">0</VALUE>
<CHNAME type="STR">傳輸通道</CHNAME>
<COMMENT type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPChannel5">
<VALUE type="ENUM">0</VALUE>
<CHNAME type="STR">傳輸通道</CHNAME>
<COMMENT type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPChannel6">
<VALUE type="ENUM">0</VALUE>
<CHNAME type="STR">傳輸通道</CHNAME>
<COMMENT type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPBigImageFile">
<VALUE type="STR">/$(IP)/$(ChannelID)/$(Year)/$(Month)/$(Day)/$(Hour)/$(Year)$(Month)$(Day)$(Hour)$(Minute)$(Second)_$(PlateID)_$(ImageID).jpg</VALUE>
<CHNAME type="STR">大圖存儲路徑</CHNAME>
<COMMENT type="STR">大圖存儲路徑</COMMENT>
<DEFAULT type="STR">/$(IP)/$(ChannelID)/$(Year)/$(Month)/$(Day)/$(Hour)/$(Year)$(Month)$(Day)$(Hour)$(Minute)$(Second)_$(PlateID)_$(ImageID).jpg</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="PlateSmallFile">
<VALUE type="STR">/$(IP)/$(ChannelID)/$(Year)/$(Month)/$(Day)/$(Hour)/$(Year)$(Month)$(Day)$(Hour)$(Minute)$(Second)_$(PlateID).bmp</VALUE>
<CHNAME type="STR">小圖存儲路徑</CHNAME>
<COMMENT type="STR">小圖存儲路徑</COMMENT>
<DEFAULT type="STR">/$(IP)/$(ChannelID)/$(Year)/$(Month)/$(Day)/$(Hour)/$(Year)$(Month)$(Day)$(Hour)$(Minute)$(Second)_$(PlateID).bmp</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="PlateBinFile">
<VALUE type="STR">/$(IP)/$(ChannelID)/$(Year)/$(Month)/$(Day)/$(Hour)/$(Year)$(Month)$(Day)$(Hour)$(Minute)$(Second)_$(PlateID).bin</VALUE>
<CHNAME type="STR">二值圖存儲路徑</CHNAME>
<COMMENT type="STR">二值圖存儲路徑</COMMENT>
<DEFAULT type="STR">/$(IP)/$(ChannelID)/$(Year)/$(Month)/$(Day)/$(Hour)/$(Year)$(Month)$(Day)$(Hour)$(Minute)$(Second)_$(PlateID).bin</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="PlateTxtFile">
<VALUE type="STR">/$(IP)/$(ChannelID)/$(Year)/$(Month)/$(Day)/$(Hour)/$(Year)$(Month)$(Day)$(Hour)$(Minute)$(Second)_$(PlateID).txt</VALUE>
<CHNAME type="STR">車牌文件存儲路徑</CHNAME>
<COMMENT type="STR">車牌文件存儲路徑</COMMENT>
<DEFAULT type="STR">/$(IP)/$(ChannelID)/$(Year)/$(Month)/$(Day)/$(Hour)/$(Year)$(Month)$(Day)$(Hour)$(Minute)$(Second)_$(PlateID).txt</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="InfFile">
<VALUE type="STR">/$(IP)/$(ChannelID)/$(Year)/$(Month)/$(Day)/$(Hour)/$(Year)$(Month)$(Day)$(Hour)$(Minute)$(Second)_$(PlateID).inf</VALUE>
<CHNAME type="STR">附加信息存儲路徑</CHNAME>
<COMMENT type="STR">附加信息存儲路徑</COMMENT>
<DEFAULT type="STR">/$(IP)/$(ChannelID)/$(Year)/$(Month)/$(Day)/$(Hour)/$(Year)$(Month)$(Day)$(Hour)$(Minute)$(Second)_$(PlateID).inf</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="VideoFile">
<VALUE type="STR">/$(IP)/$(ChannelID)/$(Year)/$(Month)/$(Day)/$(Hour)/$(Year)$(Month)$(Day)$(Hour)$(Minute)$(Second)_$(PlateID).avi</VALUE>
<CHNAME type="STR">錄像文件存儲路徑</CHNAME>
<COMMENT type="STR">錄像文件存儲路徑</COMMENT>
<DEFAULT type="STR">/$(IP)/$(ChannelID)/$(Year)/$(Month)/$(Day)/$(Hour)/$(Year)$(Month)$(Day)$(Hour)$(Minute)$(Second)_$(PlateID).avi</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="ResultType">
<VALUE type="ENUM">1</VALUE>
<CHNAME type="STR">結果類型</CHNAME>
<COMMENT type="STR">0:歷史結果;1:實時結果</COMMENT>
<DEFAULT type="INT">1</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:歷史結果;1:實時結果</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="StartTime">
<VALUE type="INT">0</VALUE>
<CHNAME type="STR">歷史結果開始傳輸時間</CHNAME>
<COMMENT type="STR">歷史結果開始傳輸時間,從1970年起經過的秒數</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">2147483647</MAX>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
</SECTION>
<SECTION name="Video" cname="視頻數據">
<KEY name="EnableFTP">
<VALUE type="ENUM">0</VALUE>
<CHNAME type="STR">FTP使能開關</CHNAME>
<COMMENT type="STR">0:不使能;1:使能</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:不使能;1:使能</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPServerIP">
<VALUE type="STR">172.18.11.67</VALUE>
<CHNAME type="STR">NTP服務器</CHNAME>
<COMMENT type="STR">NTP服務器IP地址</COMMENT>
<DEFAULT type="STR">172.18.11.67</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPUserName">
<VALUE type="STR">anonymous</VALUE>
<CHNAME type="STR">用戶名</CHNAME>
<COMMENT type="STR">用戶名</COMMENT>
<DEFAULT type="STR">anonymous</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPUserPasswd">
<VALUE type="STR">yetpasswd</VALUE>
<CHNAME type="STR">密碼</CHNAME>
<COMMENT type="STR">密碼</COMMENT>
<DEFAULT type="STR">yetpasswd</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPPort">
<VALUE type="INT">21</VALUE>
<CHNAME type="STR">端口號</CHNAME>
<COMMENT type="STR">端口號</COMMENT>
<DEFAULT type="INT">21</DEFAULT>
<MIN type="INT">1</MIN>
<MAX type="INT">65536</MAX>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPMode">
<VALUE type="ENUM">0</VALUE>
<CHNAME type="STR">FTP模式</CHNAME>
<COMMENT type="STR">0:被動模式;1:主動模式</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:被動模式;1:主動模式</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPChannel1">
<VALUE type="ENUM">0</VALUE>
<CHNAME type="STR">傳輸通道</CHNAME>
<COMMENT type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPChannel2">
<VALUE type="ENUM">0</VALUE>
<CHNAME type="STR">傳輸通道</CHNAME>
<COMMENT type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPChannel3">
<VALUE type="ENUM">0</VALUE>
<CHNAME type="STR">傳輸通道</CHNAME>
<COMMENT type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPChannel4">
<VALUE type="ENUM">0</VALUE>
<CHNAME type="STR">傳輸通道</CHNAME>
<COMMENT type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPChannel5">
<VALUE type="ENUM">0</VALUE>
<CHNAME type="STR">傳輸通道</CHNAME>
<COMMENT type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="FTPChannel6">
<VALUE type="ENUM">0</VALUE>
<CHNAME type="STR">傳輸通道</CHNAME>
<COMMENT type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:不傳輸該通道數據;1:傳輸該通道數據</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="VideoFile">
<VALUE type="STR">/$(IP)/$(ChannelID)/$(Year)/$(Month)/$(Day)/$(Hour)/$(Year)$(Month)$(Day)$(Hour)$(Minute)$(Second).avi</VALUE>
<CHNAME type="STR">錄像文件存儲路徑</CHNAME>
<COMMENT type="STR">錄像文件存儲路徑</COMMENT>
<DEFAULT type="STR">/$(IP)/$(ChannelID)/$(Year)/$(Month)/$(Day)/$(Hour)/$(Year)$(Month)$(Day)$(Hour)$(Minute)$(Second).avi</DEFAULT>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="VideoSize">
<VALUE type="INT">1</VALUE>
<CHNAME type="STR">視頻文件時長,單位爲分鐘</CHNAME>
<COMMENT type="STR">視頻文件時長,單位爲分鐘</COMMENT>
<DEFAULT type="INT">1</DEFAULT>
<MIN type="INT">1</MIN>
<MAX type="INT">10</MAX>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="VideoType">
<VALUE type="ENUM">1</VALUE>
<CHNAME type="STR">H264視頻類型</CHNAME>
<COMMENT type="STR">0:歷史視頻;1:實時視頻</COMMENT>
<DEFAULT type="INT">1</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">1</MAX>
<RANK type="INT">5</RANK>
<ENUM type="STR">0:歷史視頻;1:實時視頻</ENUM>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
<KEY name="StartTime">
<VALUE type="INT">0</VALUE>
<CHNAME type="STR">歷史視頻開始傳輸時間</CHNAME>
<COMMENT type="STR">歷史視頻開始傳輸時間,從1970年起經過的秒數</COMMENT>
<DEFAULT type="INT">0</DEFAULT>
<MIN type="INT">0</MIN>
<MAX type="INT">2147483647</MAX>
<RANK type="INT">5</RANK>
<ONLYREAD type="INT">0</ONLYREAD>
</KEY>
</SECTION>
</SECTION>
</HvParam>
</HvParamDoc>
三c# 遞歸轉換XML配置參數代碼
/// <summary>
/// 遞歸轉換XML配置參數
/// </summary>
/// <param name="dsec">父節</param>
/// <param name="sectionNode">父節點</param>
/// <param name="paramGroup">節點集合</param>
/// <param name="paramKeys">鍵值集合</param>
protected void XMLToParameter(ParameterSection ParentSection, XmlNode sectionNode, List<ParameterSection> paramGroup, List<ParameterKey> paramKeys)
{
ParameterSection dsec = new ParameterSection();
paramGroup.Add(dsec);
dsec.SectionID = paramGroup.Count;
dsec.Name = sectionNode.Attributes["name"].Value.Trim();
if (ParentSection != null)
{
dsec.Path = ParentSection.Path + "//" + dsec.Name;
dsec.ParentSectionID = ParentSection.SectionID;
ParentSection.Sections.Add(dsec);
}
else
{
dsec.Path = dsec.Name;
dsec.ParentSectionID = 0;
}
if (sectionNode.Attributes["cname"] != null) dsec.CHName = sectionNode.Attributes["cname"].Value.Trim();
int nValue = 0;
foreach (XmlNode child in sectionNode.ChildNodes)
{
if (child.Name == "KEY")
{
ParameterKey key = new ParameterKey();
key.ReadOnly = false;
key.Name = child.Attributes["name"].Value.Trim();
string url = string.Format("{0}//{1}", dsec.Name, key.Name);
ParameterSection p = dsec;
while (p.ParentSectionID != 0)
{
p = paramGroup.First(r => r.SectionID == p.ParentSectionID);
url = string.Format("{0}//{1}", p.Name, url);
}
key.Path = url;
foreach (XmlNode keyChild in child.ChildNodes)
{
switch (keyChild.Name.ToUpper())
{
case "VALUE":
key.Type = keyChild.Attributes["type"].Value.Trim();
try
{
if (key.Type == ParameterKey.STR_TYPR)
{
//回車換行特殊轉換
key.Value = keyChild.InnerText.Trim().Replace("{0D0A}", System.Environment.NewLine);
}
else
key.Value = keyChild.InnerText.Trim();
}
catch
{
key.Value = key.Min;
}
if (key.Type == ParameterKey.STR_TYPR && key.Value.Trim() == "NULL") key.Value = "";
break;
case "DEFAULT":
key.Default = keyChild.InnerText.Trim();
break;
case "MIN":
key.Min = keyChild.InnerText.Trim();
break;
case "MAX":
key.Max = keyChild.InnerText.Trim();
break;
case "CHNAME":
key.CHName = keyChild.InnerText.Trim();
break;
case "COMMENT":
key.Comment = keyChild.InnerText.Trim();
break;
case "ENUM":
{
string enums = keyChild.InnerText.Trim();
string[] es = enums.Split(';');
foreach (string str in es)
{
string[] items = str.Split(':');
if (int.TryParse(items[0].Trim(), out nValue))
{
key.AddEnumItem(new EnumItem(items[1].Trim(), nValue));
}
}
}
break;
case "ONLYREAD":
if (int.TryParse(keyChild.InnerText, out nValue))
{
key.ReadOnly = nValue == 1;
}
break;
case "RANK":
if (int.TryParse(keyChild.InnerText, out nValue))
{
key.Rank = nValue;
}
break;
}
}
if (key.Rank > 0)
{
//加入到設備參數列表
paramKeys.Add(key);
//加入到節點中
dsec.KeySet.Add(key);
}
}
else if (child.Name == "SECTION")
{
XMLToParameter(dsec, child, paramGroup, paramKeys);
}
}
}
四 QT遞歸轉換XML配置參數代碼
/// <summary>
/// 遞歸轉換XML配置參數
/// </summary>
/// <param name="dsec">父節</param>
/// <param name="sectionNode">父節點</param>
/// <param name="paramGroup">節點集合</param>
/// <param name="paramKeys">鍵值集合</param>
void XMLToParameter(ParameterSection* ParentSection,
QDomNode& sectionNodeT,
QList<ParameterSection *> ¶mGroup,
QList<ParameterKey *> ¶mKeys,
QObject* parent)
{
ParameterSection* dsec = new ParameterSection(parent);
if(nullptr == dsec)
{
qDebug()<<"cannot new child ParameterSection";
return;
}
QDomElement sectionNode = sectionNodeT.toElement(); //將其轉換爲元素
paramGroup.append(dsec);
dsec->SectionID = paramGroup.size();
dsec->Name = sectionNode.attribute("name");
if( nullptr != ParentSection)
{
dsec->Path = ParentSection->Path + "//" + dsec->Name;
dsec->ParentSectionID = ParentSection->SectionID;
ParentSection->Sections.append(dsec);
}
else
{
dsec->Path = dsec->Name;
dsec->ParentSectionID = 0;
}
if (!sectionNode.attribute("cname").isNull() && !sectionNode.attribute("cname").isEmpty() )
dsec->CHName = sectionNode.attribute("cname").trimmed();
int nValue = 0;
for( int i = 0; i<sectionNode.childNodes().size(); i++)
{
QDomNode childNode = sectionNode.childNodes().at(i);
QDomElement child = childNode.toElement(); //將其轉換爲元素
if (child.tagName() == "KEY")
{
ParameterKey* key = new ParameterKey(parent);
key->ReadOnly = false;
key->Name = child.attribute("name").trimmed();
QString url = QString("%1//%2").arg(dsec->Name).arg(key->Name);
ParameterSection* p = dsec;
bool find = false;
while (p->ParentSectionID != 0)
{
for(int k =0; k<paramGroup.size(); k ++)
{
if(p->ParentSectionID == paramGroup.at(k)->ParentSectionID)
{
p = paramGroup.at(k);
url = QString("%1//%2").arg( p->Name).arg(url);
find = true;
break;
}
}
if(find)
{
break;
}
}
key->Path = url;
for (int j=0; j<child.childNodes().size(); j++)
{
QDomNode keyChildNode = child.childNodes().at(j);
QDomElement keyChild = keyChildNode.toElement(); //將其轉換爲元素
QString strNameTemp = keyChild.tagName().toUpper();
if( "VALUE" == strNameTemp)
{
key->Type = keyChild.attribute("type").trimmed();
if (key->Type == STR_TYPR)
{
//回車換行特殊轉換
key->Value = keyChild.text().trimmed().replace("0D0A", "\n");
}
else
{
key->Value = keyChild.text().trimmed();
}
if (
(key->Type == STR_TYPR)
&& (key->Value.trimmed() == "NULL")
)
{
key->Value = "";
}
}
else if( "DEFAULT" == strNameTemp)
{
key->Default = keyChild.text().trimmed();
}
else if( "MIN" == strNameTemp)
{
key->Min = keyChild.text().trimmed();
}
else if( "MAX" == strNameTemp){
key->Max = keyChild.text().trimmed();
}
else if( "CHNAME" == strNameTemp){
key->CHName = keyChild.text().trimmed();
}
else if( "COMMENT" == strNameTemp){
key->Comment = keyChild.text().trimmed();
}
else if( "ENUM" == strNameTemp)
{
QString enums = keyChild.text().trimmed();
QStringList es = enums.split(';');
for (QString str : es)
{
QStringList items = str.split(':');
QString str0 = items.at(0).trimmed();
QString str1 = items.at(1).trimmed();
key->AddEnumItem( new EnumItem(str1, atoi(str0.toLocal8Bit().data()), parent) );
}
}
else if( "ONLYREAD" == strNameTemp)
{
//todo(liyh) 判斷keyChild.text().存在
key->ReadOnly = nValue == atoi(keyChild.text().toLocal8Bit().data());
}
else if( "RANK" == strNameTemp)
{
//todo(liyh) 判斷keyChild.text().存在
key->Rank = atoi(keyChild.text().toLocal8Bit().data());
}
}
if (key->Rank > 0)
{
//加入到設備參數列表
paramKeys.append(key);
//加入到節點中
dsec->KeySet.append(key);
}
}
else if (child.tagName() == "SECTION")
{
XMLToParameter(dsec, child, paramGroup, paramKeys, parent);
}
}
}
五 QT下xml轉ini的代碼
//總功能:xml轉換爲ini
QTextCodec *codec = QTextCodec::codecForLocale();
QObject objParent;
QList<ParameterSection*> parameterGroups;
QList<ParameterKey*> parameters;
// //載入xml
QDomDocument doc;
if(!doc.setContent(codec->toUnicode(szXML)))
{
strcpy(pSignalwayDevice->m_szStatus, tr("獲取參數失敗,請確認參數的格式").toStdString().c_str());
HVAPI_CloseEx(h);
break;
}
//開始解析
QDomElement docElem = doc.documentElement(); //返回根元素
QDomNode nHvParam = docElem.firstChild(); //返回根節點的第一個子節點//此節點爲HvParam
QDomNode n = nHvParam.firstChild(); //返回根節點的第一個子節點,此時爲關注的key和section
//解析section和key
while(!n.isNull())
{ //如果節點不爲空
XMLToParameter(nullptr, n, parameterGroups, parameters, &objParent);
n = n.nextSibling(); //下一個兄弟節點
}
//打開文件
FILE* pFile;
if( (pFile = fopen(fileName.toLocal8Bit().data(), "wb")) == nullptr)
{
std::cerr << "Cannot open file for writing: "
<< __FUNCTION__ << std::endl;
strcpy(pSignalwayDevice->m_szStatus, tr("獲取參數失敗,無法打開文件").toStdString().c_str());
HVAPI_CloseEx(h);
break;
}
int rank = SECURERANK::user;
for(int i=0; i<parameterGroups.size(); i++)
{
ParameterSection* pg = parameterGroups.at(i);
auto itRank = std::find_if(pg->KeySet.begin(),
pg->KeySet.end(),
[&]( const ParameterKey* pkItem) -> bool{ return pkItem->Rank >= rank; }
);
if(pg->KeySet.end() != itRank)
{
QString strSection = pg->Name;
ParameterSection* parent = nullptr;
//尋找父節點路徑名
auto it = std::find_if( parameterGroups.begin(),
parameterGroups.end(),
[&]( const ParameterSection* psItem) -> bool{ return psItem->SectionID == pg->ParentSectionID; } );
while( parameterGroups.end() != it)
{
parent = *it;
strSection = QString("%1//%2")
.arg(parent->Name)
.arg(strSection);
it = std::find_if( parameterGroups.begin(),
parameterGroups.end(),
[&]( const ParameterSection* psItem) -> bool{ return psItem->SectionID == parent->ParentSectionID; } );
}
strSection = strSection.replace("//", "\\");
QString strSectionT = "[" + strSection + "]\n";
fwrite(strSectionT.toUtf8().data(), strlen(strSectionT.toUtf8().data()), 1, pFile);
//遍歷所有key鍵
for(int k=0; k<pg->KeySet.size(); k++)
{
ParameterKey* key = pg->KeySet.at(k);
QString content = QString("%1 = %2:%3")
.arg( key->Name)
.arg(key->Type)
.arg(key->Value);
QString contentT = QString("%1;%2 %3\n")
.arg(content, -80)
.arg(key->CHName.isEmpty()? "":key->CHName.replace(";", " "))
.arg(key->Comment.isEmpty()? "":key->Comment.replace(";", " "));
fwrite(contentT.toUtf8().data(), strlen(contentT.toUtf8().data()), 1, pFile);
}
QString strNewLine = "\n";
fwrite(strNewLine.toUtf8().data(), strlen(strNewLine.toUtf8().data()), 1, pFile);
}
}
fclose(pFile);