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 *> ¶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,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,无法打开文件").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(),[&]( 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()),pFile); } QString strNewLine = "\n"; fwrite(strNewLine.toUtf8().data(),strlen(strNewLine.toUtf8().data()),pFile); } } fclose(pFile);