简体   繁体   English

XML反序列化:不同的xml架构映射到同一个C#类

[英]XML deserialize: different xml schema maps to the same C# class

One of the jobs of my program is to read customer list from a xml file and deserialize them into C# class like below: 我的程序的一个工作是从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# class: 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;}
}

but recently customer wants to change the tag name from <id> to <code> like the one below: 但最近客户希望将标签名称从<id>更改为<code> ,如下所示:

<?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>

The value for 'code' will have the same meaning with previous tag 'id'. “code”的值与之前的标记“id”具有相同的含义。 And they want that during transition the program should be amended so it recognizes both tags for a period of time. 他们希望在转换过程中修改程序,以便在一段时间内识别这两个标记。

Is there any easy method to achieve that? 有没有简单的方法来实现这一目标? Thanks. 谢谢。

Why don't you use one private field and use two different getters/setters? 为什么不使用一个私有字段并使用两个不同的getter / setter? As long as both tags do not appear in the XML, this will work. 只要两个标记都没有出现在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;}}
}

As far as I know, you can't do that with XML attributes. 据我所知,你不能用XML属性做到这一点。 You will have to implement IXmlSerializable and take control of the deserialization process yourself. 您必须实现IXmlSerializable并自己控制反序列化过程。 Here are a couple of links to get you started: 以下是一些可以帮助您入门的链接:

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

Proper way to implement IXmlSerializable? 正确的方法来实现IXmlSerializable?

I haven't tried it, but it seems to be you need to do something like this: 我没有尝试过,但似乎你需要做这样的事情:

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;
        }
    }
}

There's probably a few typos in the above, but I think that's the general idea. 上面可能有一些拼写错误,但我认为这是一般的想法。

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

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