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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章