无法将类型为“System.Xml.XmlComment”的对象强制转换为类型“System.Xml.XmlElement”。---C#

解析XML文件时,因未处理XmlComment类型导致强制转换错误。通过调整类型检查逻辑,确保仅处理XmlElement类型,避免异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近自己负责维护的一个软件出现了如下错误:

Exception: 无法将类型为“System.Xml.XmlComment”的对象强制转换为类型“System.Xml.XmlElement”。

收到产品线发来的bug通知,我很快就意识到了在什么地方出错。之前公司软件升级时,有一个xml文件需要我们plc这边负责升级(由原来的lua文件格式转为xml格式)。解析xml的代码部分如下:

 var doc = new XmlDocument();
 doc.Load(Path)         
 foreach (XmlElement childNode in doc.DocumentElement.ChildNodes)
    {
         if(childNode.Name == "I")
           {
               .........
           }  
          .........
    }

待解析的xml文件的内容格式为:

<?xml version="1.0" encoding="utf-8"?>
<IO>
   <I L="xxx.yyy" R="bbb.ccc" />
   <I L="ccc.ddd" R="ttt.iii" />
  <O L="rrr.eee" R="eee.ccc" />
   <O L="ppp.eee" R="vvv.ccc" />
</IO>

按理来说,待解析的xml文件只要符合上述的格式,都是可以解析成功的。之前也是做了非常“充分”的测试,所以组件的alpha(不能保证没有bug的)版本就发出去了,奈何这个alpha版本组件在测试部门的测试下也没有找到这个隐藏的bug。那到底是怎么样才会出现上述的bug呢。

非常简单的重现该bug就是在解析的xml文件中进行注释内容的添加:

<?xml version="1.0" encoding="utf-8"?>
<IO>
   <I L="xxx.yyy" R="bbb.ccc" />
   <!--<I L="ccc.ddd" R="ttt.iii" />
  <O L="rrr.eee" R="eee.ccc" />-->
   <O L="ppp.eee" R="vvv.ccc" />
</IO>

这个添加注释的操作是合理的,但是在代码中解析时却是“不合理的”,因为doc去解析xml获得的ChildNodes集合中并非所有元素的类型都是XmlElement。就拿注释的内容来说,它就是XmlComment类型。于是乎,用户输入的xml文件内容包含非XmlElement类型的子节点时发生了报错。

那么怎么改呢,超级简单,只要用foreach去遍历ChildNodes子节点时,我先用object类型变量node去获取,然后转为XmlElement类型变量childNode,转换成功则继续(childNode不为null),否则跳过当前循环。

 var doc = new XmlDocument();
 doc.Load(Path)         
 foreach (object node in doc.DocumentElement.ChildNodes)
    {
         XmlElement childNode = childNode as XmlElement;
         if(childNode == null)
             continue;

         if(childNode.Name == "I")
           {
               .........
           }  
          .........
    }

总结一下:遇到遍历某个集合的逻辑时,先判断自己要处理的是什么类型,以及集合里面大概都有什么类型。上述修改的做法是最可靠的,不管你集合里面有什么类型,我只关心我要处理的类型,否则pass掉。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值