繁体   English   中英

使用空元素反序列化Xml

[英]Deserialize Xml with empty elements

考虑以下XML:

<a>
    <b>2</b>
    <c></c>
</a>  

我需要将这个xml反序列化为一个对象。 所以,我写了下面的课。

public class A
{
    [XmlElement("b", Namespace = "")]
    public int? B { get; set; }

    [XmlElement("c", Namespace = "")]
    public int? C { get; set; }

}

因为我正在使用nullables,所以我期待在解析上面的xml时,我会得到一个带有null C属性的对象A.

而不是这个,我得到一个异常,告诉文档有错误。

缺少元素和null元素之间存在差异。

缺少元素<a><b>2</b></a> 这里C将使用DefaultValue属性获取您指定的任何默认值,如果没有显式默认值,则为null。

null元素<a><b>2</b><c xs:Nil='true'/></a> 在这里你将得到null。

当您执行<a><b>2</b><c></c><a/> ,xml序列化程序将尝试将string.Empty解析为整数,将正确失败。

由于您的提供程序生成无效的xml,因此如果使用XmlSerializer,则需要执行此操作:

[XmlRoot(ElementName = "a")]
public class A
{
    [XmlElement(ElementName = "b")]
    public int? B { get; set; }

    [XmlElement(ElementName = "c")]
    public string _c { get; set; }

    public int? C
    {
        get
        {
            int retval;

            return !string.IsNullOrWhiteSpace(_c) && int.TryParse(_c, out retval) ? (int?) retval : null;
        }
    }
}

或使用DataContractSerializer略微好一些

[DataContract(Name="a")]
public class A1
{
    [DataMember(Name = "b")]
    public int? B { get; set; }

    [DataMember(Name = "c")]
    private string _c { get; set; }

    public int? C
    {
        get
        {
            int retval;

            return !string.IsNullOrWhiteSpace(_c) && int.TryParse(_c, out retval) ? (int?)retval : null;
        }
    }
}

虽然如果这是一个问题,DataContractSerializer不支持属性。

要反序列化示例中的'c'之类的空标记:

    <foo>
        <b>2</b>
        <c></c>
    </foo>

我用这种方法。 首先,它使用LINQ从XML文件中删除null或空元素,然后将没有null或空标记的新文档反序列化到Foo类。

    public static Foo ReadXML(string file)
    {
            Foo foo = null;
            XDocument xdoc = XDocument.Load(file);
            xdoc.Descendants().Where(e => string.IsNullOrEmpty(e.Value)).Remove();

            XmlSerializer xmlSer = new XmlSerializer(typeof(Foo));
            using (var reader = xdoc.Root.CreateReader())
            {
                foo = (Foo)xmlSer.Deserialize(reader);
                reader.Close();
            }
            if (foo == null)
                foo = new Foo();

            return foo;
    }

这将为您提供缺少的属性的默认值。

    foo.b = 2;
    foo.c = 0; //for example, if it's an integer

我从这个链接加入了信息:

删除空XML标记

使用XDocument作为XmlSerializer.Deserialize的源?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM