简体   繁体   中英

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

[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:

<?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'. 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? As long as both tags do not appear in the XML, this will work.

[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. You will have to implement IXmlSerializable and take control of the deserialization process yourself. Here are a couple of links to get you started:

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

Proper way to implement 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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