0

i have structure in XML file:

<Employee>
    <EmpId>1</EmpId>
    <Name>Sam</Name>
    <Phone Type="Home">423-555-0124</Phone>
    <Phone Type="Work">424-555-0545</Phone>
</Employee>

and class:

public class Phone
{
    [XmlAttribute("type")]
    public string Type { get; set; }
    [XmlText]
    public string Value { get; set; }
}
public class Employee
{
    [XmlElement("EmpId")]
    public int Id { get; set; }

    [XmlElement("Name")]
    public string Name { get; set; }

    [XmlElement("Phone", ElementName = "Phone")]
    public Phone phone_home { get; set; }

    [XmlElement("Phone2", ElementName = "Phone")]
    public Phone phone_work { get; set; }

    public Employee() { }
    public Employee(string home, string work)
    {
        phone_home = new Phone()
        {
            Type = "home",
            Value = home
        };
        phone_work = new Phone()
        {
            Type = "work",
            Value = work
        };
    }
    public static List<Employee> SampleData()
    {
        return new List<Employee>()
        {
            new Employee("h1","w1"){
                Id   = 1,
                Name = "pierwszy",
            },
            new Employee("h2","w2"){
                Id   = 2,
                Name = "drugi",
            }
        };
    }
}

but my problem is that i can't add Two XmlElement with names "Phone". When i try to compile it then i have exception about two same name of XmlElement (repeat: Phone). How can i resolve it?

Marek Woźniak
  • 1,766
  • 16
  • 34

3 Answers3

4

Use this:

[XmlType("Phone")]
public class Phone
{
    [XmlAttribute("type")]
    public string Type { get; set; }
    [XmlText]
    public string Value { get; set; }
}

[XmlType("Employee")]
public class Employee
{
    [XmlElement("EmpId", Order = 1)]
    public int Id { get; set; }

    [XmlElement("Name", Order = 2)]
    public string Name { get; set; }

    [XmlElement(ElementName = "Phone", Order = 3)]
    public Phone phone_home { get; set; }

    [XmlElement(ElementName = "Phone", Order = 4)]
    public Phone phone_work { get; set; }

    public Employee() { }
    public Employee(string home, string work)
    {
        phone_home = new Phone()
        {
            Type = "home",
            Value = home
        };
        phone_work = new Phone()
        {
            Type = "work",
            Value = work
        };
    }

public static List<Employee> SampleData()
    {
        return new List<Employee>()
    {
        new Employee("h1","w1"){
            Id   = 1,
            Name = "pierwszy",
        },
        new Employee("h2","w2"){
            Id   = 2,
            Name = "drugi",
        }
    };
    }
}

Serialize code:

var employees = Employee.SampleData();

System.Xml.Serialization.XmlSerializer x = 
new System.Xml.Serialization.XmlSerializer(employees.GetType());

x.Serialize(Console.Out, employees);

Here is your result:

<?xml version="1.0" encoding="windows-1250"?>
<ArrayOfEmployee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Employee>
    <EmpId>1</EmpId>
    <Name>pierwszy</Name>
    <Phone type="home">h1</Phone>
    <Phone type="work">w1</Phone>
  </Employee>
  <Employee>
    <EmpId>2</EmpId>
    <Name>drugi</Name>
    <Phone type="home">h2</Phone>
    <Phone type="work">w2</Phone>
  </Employee>
</ArrayOfEmployee>
Major
  • 5,948
  • 2
  • 45
  • 60
  • it works! I tried with same way (Order), but i wrote number 1 and 2..Thanks you so much! P.S it works too without [XmlType(..)] for Phome – Marek Woźniak Aug 07 '14 at 22:03
0

You are using the [XmlRoot] attribute on your Phone class. [XmlRoot] defines the root of the document, and there can only be one root element in an xml document. Your Employee class should have the [XmlRoot] attribute based on the xml you showed us.

There should be no attributes on your Phone class, only on the Employee.Phone member of your Employee class, as you have it now.

Cam Bruce
  • 5,632
  • 19
  • 34
  • Error 16 Attribute 'XmlElement' is not valid on this declaration type. It is only valid on 'property, indexer, field, param, return' declarations. M:\LINQ TO OBJECT 4.0\MOJE KODY\XML\ParserXMLtoclass\ParserXMLtoclass\Employee.cs 12 6 ParserXMLtoclass – Marek Woźniak Aug 07 '14 at 21:06
  • Sorry, clarified my answer. There shouldn't be any attributes on the `Phone` class. `XmlRoot` should be only on `Employee` – Cam Bruce Aug 07 '14 at 21:09
0

Consider replacing the work and home Phone properties on your Employee class with a property that is a List of Phone objects. This is more flexible (in case you end up supporting other types than work or home), and .net xml serialization knows how to deal with it.

See Is it possible to deserialize XML into List<T>? .

Just replace the phone_home and phone_work properties with this:

[XmlElement("Phone"]
public List<Phone> Phones { get; set; }

The serialized xml should be the same as what you've specified above.

Community
  • 1
  • 1
Jerry Federspiel
  • 1,504
  • 10
  • 14