首页 > 解决方案 > 如何在 C# 中反序列化 XML 时处理自闭标签问题

问题描述

如果 XML 字符串包含自封闭标签,则无法反序列化。错误:XML 文档中存在错误 (4, 1)。如果我将数据类型更改为字符串,我可以避免。但我需要维护 int 数据类型。不使用可为空的 int。

public class model
{
       [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    public partial class details
    {

                private string name;
                private int id;
    }
}

public void process()
{
   string text = "<?xml version="1.0" encoding="UTF-8"?>
                 <details>
                 <name>ABC</name>
                 <id /> 
                 </details>"


    Deserialize<model>(text);

}

    public T Deserialize<T>(string input) where T : class
   {
     try
      {

                System.Xml.Serialization.XmlSerializer ser = new 
                System.Xml.Serialization.XmlSerializer(typeof(T));

                using StringReader sr = new StringReader(input);
                return (T)ser.Deserialize(sr);
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "error");
                return null;
            }
            finally { }
        }
  }

标签: c#.net

解决方案


Let's create a model class like this:

[XmlRoot("details")]
public class Details
{
    [XmlElement("name")]
    public string Name { get; set; }
    public int? Id { get; set; }
}

Then, when creating a serializer, we will subscribe it to the UnknownElement event. In the event handler, we manually check the content of the id element and set the desired values.

static void Main()
{
    string input = @"<?xml version='1.0' encoding='UTF-8'?>
        <details>
            <name>ABC</name>
            <id />
        </details>";

    var serializer = new XmlSerializer(typeof(Details));
    serializer.UnknownElement += Serializer_UnknownElement;

    Details details = null;
    using (var stringReader = new StringReader(input))
    {
        details = (Details)serializer.Deserialize(stringReader);
    }
    Console.WriteLine(details.Name);
    Console.WriteLine(details.Id);
}

private static void Serializer_UnknownElement(object sender, XmlElementEventArgs e)
{
    if (e.Element.Name == "id")
    {
        var details = (Details)e.ObjectBeingDeserialized;

        if (string.IsNullOrWhiteSpace(e.Element.InnerText))
            details.Id = null;
        else
            details.Id = int.Parse(e.Element.InnerText);
    }
}

推荐阅读