You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XML元素反序列化失败求助:无法解析含ImportantNode的节点

XML反序列化问题:解析包含XmlElement集合的XML内容

我正尝试反序列化包含XmlElement集合的XML,需要解析<First>和<second>元素,其中<ImportantNode>内的内容是核心,<third>元素可以暂时忽略。目前卡在反序列化执行环节。

对应的XML内容

<configuration>
  <objects>
        <!-- this is a comment -->  
         <First>
          <param name="Name" type="string">FirstName</param>
          <param name="Type" type="string">FirstType</param>
          <SomeElement>
               <SomeElement1>
                  <param name="Name" type="string">AAA</param>
                  <param name="Name2" type="string">BBB</param>
              </SomeElement1>
          </SomeElement>
          <param name="param1" type="string">1</param>
          <param name="param2" type="int">2</param>
          <param name="param3" type="float">3</param>
          <ImportantNode>
            <ImportantChildNode1>
              <param name="minValue" type="float">1</param>
              <param name="maxValue" type="float">100</param>
            </ImportantChildNode1>
            <ImportantChildNode2>
              <param name="minValue" type="float">1</param>
              <param name="maxValue" type="float">100</param>
            </ImportantChildNode2> <!-- 原XML此处为</IR>,是错误的,已修正 -->
        </ImportantNode>
        <elements>
          <element>
              <param name="paramName1" type="bool">true</param>
          </element>
        </elements>
      </First>
      <second>
          <param name="Name" type="string">2</param>
          <param name="Type" type="string">3</param>
          <ImportantNode>
            <ImportantChildNode1>
              <param name="minValue" type="float">2</param>
              <param name="maxValue" type="float">20</param>
            </ImportantChildNode1>
            <ImportantChildNode2>
              <param name="minValue" type="float">3</param>
              <param name="maxValue" type="float">30</param>
            </ImportantChildNode2> <!-- 原XML此处为</IR>,是错误的,已修正 -->
          </ImportantNode>
      </second>
      <third>
          <param name="Name" type="string">3</param>
          <param name="Type" type="string">4</param>
          <AAAA>
            <param name="DDD" type="string">XXX</param>
          </AAAA>
          <BBBB>
            <param name="DDD" type="string">ZZZ</param>
          </BBBB>
          <param name="Param1" type="string">6</param>
          <param name="Param2" type="string">301</param>
      </third>
    
    </objects>
</configuration>

相关类定义

[Serializable]
[XmlRoot(ElementName = "ImportantNode")]
public class ImportantNode
{
    [XmlElement(ElementName = "ImportantChildNode1")]
    public Param ImportantChildNode1Params { get; set; }
    [XmlElement(ElementName = "ImportantChildNode2")]
    public Param ImportantChildNode2Params { get; set; }
}

 public class Param
{
    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }
    
    /*
    [XmlAttribute(AttributeName = "type")]
    public string type { get; set; }*/
    [XmlText]
    public string Value { get; set; }
}

[Serializable]
public class DeserializeObject
{
    [XmlArrayItem("param")]
    public List<Param> Params { get; set; }
    [XmlElement (ElementName ="ImportantNode")]
    public ImportantNode ImportantNodeParams { get; set; }
}

反序列化相关代码

IEnumerable<DeserializeObject> DeserializeObjectsList;
XmlReaderSettings readSettings = new XmlReaderSettings();
readSettings.IgnoreComments = true;

string filePath = "<xml file path>";

//using (XmlReader reader = XmlReader.Create(filePath, readSettings)
XmlReader reader = XmlReader.Create(filePath, readSettings);
XmlDocument filedoc = new XmlDocument();
filedoc.Load(reader/*filePath*/);


//using var fileStream = new FileStream(filePath, FileMode.Open);
XmlNodeList xmlNodeList = filedoc["configuration"].GetElementsByTagName("objects");

if (xmlNodeList == null)
{
    throw new Exception("configuration file problem");
}
DeserializeObject dObject = new DeserializeObject();
XmlSerializer serializer = new XmlSerializer(dObject.GetType());

var objects = xmlNodeList[0].ChildNodes;

foreach (XmlElement object in objects)
{
    var sElement = object.InnerXml;
    //string AAA = sElement.ToString();
    StringReader SR = new StringReader(/*sElement.InnerXml*//*sElement*/object.OuterXml);
    var deserializedObject = serializer.Deserialize(SR);
    dObject = (DeserializeObject)serializer.Deserialize(SR);
}

问题分析与修复方案

1. XML结构错误

原XML中<ImportantChildNode2>的闭合标签写成了</IR>,这会直接导致XML解析失败,必须修正为</ImportantChildNode2>。

2. 类属性标记不匹配

  • DeserializeObject的Params属性:原代码用[XmlArrayItem("param")],但XML中<param>是直接作为<First>/<second>的子元素,不是嵌套在数组节点里,应改为[XmlElement("param")]。
  • ImportantNode的子节点类型:原代码中ImportantChildNode1Params和ImportantChildNode2Params类型是Param,但XML里每个<ImportantChildNode1>包含多个<param>,需要新增一个类来承载这些参数集合。

3. 反序列化逻辑错误

  • 循环中两次调用serializer.Deserialize(SR),第一次读取后流指针到末尾,第二次会返回null,需改为只调用一次。
  • 未过滤<third>元素和文本节点(换行、空格),需判断节点类型和名称后再处理。
  • 未动态指定根节点名称:<First>和<second>是不同的根元素,直接用DeserializeObject的类型会匹配失败,需创建指定根节点的XmlSerializer。

修复后的代码

修正后的类定义

[Serializable]
[XmlRoot(ElementName = "ImportantNode")]
public class ImportantNode
{
    [XmlElement(ElementName = "ImportantChildNode1")]
    public ImportantChildNode ImportantChildNode1 { get; set; }
    
    [XmlElement(ElementName = "ImportantChildNode2")]
    public ImportantChildNode ImportantChildNode2 { get; set; }
}

// 新增类:承载每个ImportantChildNode下的param集合
public class ImportantChildNode
{
    [XmlElement("param")]
    public List<Param> Params { get; set; }
}

public class Param
{
    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }
    
    [XmlAttribute(AttributeName = "type")]
    public string Type { get; set; }
    
    [XmlText]
    public string Value { get; set; }
}

[Serializable]
public class DeserializeObject
{
    [XmlElement("param")]
    public List<Param> Params { get; set; }
    
    [XmlElement(ElementName = "ImportantNode")]
    public ImportantNode ImportantNodeParams { get; set; }
}

修正后的反序列化代码

List<DeserializeObject> deserializeObjectsList = new List<DeserializeObject>();
XmlReaderSettings readSettings = new XmlReaderSettings();
readSettings.IgnoreComments = true;

string filePath = "<xml file path>";

using (XmlReader reader = XmlReader.Create(filePath, readSettings))
{
    XmlDocument filedoc = new XmlDocument();
    filedoc.Load(reader);

    XmlNode objectsNode = filedoc.SelectSingleNode("//configuration/objects");
    if (objectsNode == null)
    {
        throw new Exception("configuration file problem");
    }

    foreach (XmlNode node in objectsNode.ChildNodes)
    {
        // 只处理First和second元素,跳过文本节点和third
        if (node.NodeType != XmlNodeType.Element || (node.Name != "First" && node.Name != "second"))
            continue;

        // 动态指定根节点名称,匹配当前元素的标签名
        XmlSerializer serializer = new XmlSerializer(typeof(DeserializeObject), new XmlRootAttribute(node.Name));
        using (StringReader sr = new StringReader(node.OuterXml))
        {
            if (serializer.Deserialize(sr) is DeserializeObject deserializedObj)
            {
                deserializeObjectsList.Add(deserializedObj);
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Guy E

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 02:20:40