【问题标题】:XML deserialize: different xml schema maps to the same C# classXML 反序列化:不同的 xml 模式映射到同一个 C# 类
【发布时间】:2013-03-03 16:17:05
【问题描述】:

我的程序的一项工作是从 xml 文件中读取客户列表并将它们反序列化为 C# 类,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<customers>
    <customer>
        <name>john</name>
        <id>1</id>
    </customer>
    <customer>
        <name>mike</name>
        <id>2</id>
    </customer>
</customers>

C#类:

[XmlRoot("customers")]
public class CustomerList {
        [XmlElement("customer")]
        public Customer[] Customers { get; set; }
}

public class Customer {
    [XmlElement("name")]
    public String Name {get; set;}

    [XmlElement("id")]
    public String Id {get; set;}
}

但最近客户想将标签名称从&lt;id&gt; 更改为&lt;code&gt;,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<customers>
    <customer>
        <name>john</name>
        <code>1</code>
    </customer>
    <customer>
        <name>mike</name>
        <code>2</code>
    </customer>
</customers>

'code' 的值将与之前的标签 'id' 具有相同的含义。他们希望在过渡期间应该修改程序,以便在一段时间内识别这两个标签。

有什么简单的方法可以实现吗?谢谢。

【问题讨论】:

    标签: c# xml xml-serialization


    【解决方案1】:

    为什么不使用一个私有字段并使用两个不同的 getter/setter?只要两个标签都没有出现在 XML 中,这将起作用。

    [XmlRoot("customers")]
    public class CustomerList {
        [XmlElement("customer")]
        public Customer[] Customers { get; set; }
    }
    
    public class Customer {
        private String _id;
    
        [XmlElement("name")]
        public String Name {get; set;}
    
        [XmlElement("id")]
        public String Id {get{return _id;} set{_id = value;}}
    
        [XmlElement("code")]
        public String Code {get{return _id;} set{_id = value;}}
    }
    

    【讨论】:

    • 你是对的..干得好!不幸的是,它需要 2 个不同的属性.. 但它确实运作良好。好东西! + 1 给你!
    • @Matt 谢谢。这是临时问题的临时解决方案:)
    • @yyou 将其标记为Answered 会很好,只需单击答案旁边的绿色勾号即可。
    【解决方案2】:

    据我所知,XML 属性无法做到这一点。您必须实现IXmlSerializable 并自己控制反序列化过程。这里有几个链接可以帮助您入门:

    http://www.codeproject.com/Articles/43237/How-to-Implement-IXmlSerializable-Correctly

    Proper way to implement IXmlSerializable?

    我没试过,但似乎你需要做这样的事情:

    public void ReadXml(XmlReader reader)
    {
        var nodeType = reader.MoveToContent();
        if (nodeType == XmlNodeType.Element)
        {
            switch (reader.LocalName)
            {
                case "id":
                case "code": ID = int.Parse(reader.Value); break;
                default: break;
            }
        }
    }
    

    上面可能有一些错别字,但我认为这是大意。

    【讨论】:

    • 谢谢你,马特。我会试一试的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    相关资源
    最近更新 更多