4

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.

Yang You
  • 2,618
  • 1
  • 25
  • 32

2 Answers2

4

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;}}
}
mostruash
  • 4,169
  • 1
  • 23
  • 40
0

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.

Community
  • 1
  • 1
Matt
  • 6,787
  • 11
  • 65
  • 112