QT xml轉ini的實現(從C#轉到QT)

c# QT xml操作差異


why:接到需求把設備端的xml參數,轉換爲ini,做一箇中間的數據結構,中轉後,格式化保存爲ini格式。c#寫好了,但另外一個程序是qt寫的

目錄:

一 c#和QT在xml操作的差異差異

二實例解析的xml

三c# 遞歸轉換XML配置參數代碼

四 QT遞歸轉換XML配置參數代碼

五 QT下xml轉ini的代碼


一 c#和QT在xml操作的差異差異
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 *> &paramGroup,
                    QList<ParameterKey *> &paramKeys,
                    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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章