c# QT xml操作差异
why:接到需求把设备端的xml参数,转换为ini,做一个中间的数据结构,中转后,格式化保存为ini格式。c#写好了,但另外一个程序是qt写的
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);
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);