1

I have a sipmle class

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }

    public ICollection<Address> AllAddress { get; set; }
}

public class Address
{
    public string  Street { get; set; }
}

If i serialize People instance uses default XmlSerializer then i will get

<Person xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Id>2</Id>
    <Name>FIO FIO IFO</Name>
    <Address>
        <Street>Golden Gate</Street>
    </Address>
</Person>

How do I get this result?

<struct n="People">
     <attr n="id">2</attr >
     <attr n="name">FIO FIO IFO</attr >
     <struct n="Address">
         <attr n="street">Golden Gate</attr>
     </struct >
</struct>
3
  • 1
    Are you willing to write a custom serializer per class? Commented Dec 13, 2018 at 12:48
  • @bommelding , if xml attributes do not do this, then ready Commented Dec 13, 2018 at 12:50
  • Your inversion from <Person ... > to <struct n="Person" ...> seems to be the bigger hurdle. I don't know any serializer tat will do this. Commented Dec 13, 2018 at 12:55

1 Answer 1

2

It seems you have to convert your xml to custom format so you have to implement IXmlSerializable interface in your Person class object like.

public class Person : IXmlSerializable
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }

    public XmlSchema GetSchema() { throw new NotImplementedException(); }

    public void ReadXml(XmlReader reader)
    {
        while (reader.Read())
        {
            if (reader.Name == "attr" && reader.GetAttribute("n") == "id")
                Id = Convert.ToInt32(reader.ReadInnerXml());

            if (reader.Name == "attr" && reader.GetAttribute("n") == "name")
                Name = reader.ReadInnerXml();

            if (reader.Name == "attr" && reader.GetAttribute("n") == "street")
                Address = new Address { Street = reader.ReadInnerXml() };
        }
    }

    public void WriteXml(XmlWriter writer)
    {
        //Start "struct"
        writer.WriteStartElement("struct");
        writer.WriteAttributeString("n", "People");

        writer.WriteStartElement("attr");
        writer.WriteAttributeString("n", "id");
        writer.WriteString(Id.ToString());
        writer.WriteEndElement();

        writer.WriteStartElement("attr");
        writer.WriteAttributeString("n", "name");
        writer.WriteString(Name.ToString());
        writer.WriteEndElement();

        //Start inner "struct"
        writer.WriteStartElement("struct");
        writer.WriteAttributeString("n", "Address");

        writer.WriteStartElement("attr");
        writer.WriteAttributeString("n", "street");
        writer.WriteString(Address.Street.ToString());
        writer.WriteEndElement();

        //End inner "struct"
        writer.WriteEndElement();

        //End "struct"
        writer.WriteEndElement();
    }
}

And you can serialize and deserialize your xml like.

Person person = new Person
{
    Id = 2,
    Name = "FIO FIO IFO",
    Address = new Address { Street = "Golden Gate" }
};

//--------------------Serialization----------------------------

XmlSerializer serializer = new XmlSerializer(person.GetType());
using (StreamWriter writer = new StreamWriter(@"Path to xml file"))
{
    serializer.Serialize(writer, person);
}

//--------------------Deserialization----------------------------

using (StringReader stringReader = new StringReader(File.ReadAllText(@"Path to same xml file that generated by above serializer")))
{
    person = (Person)serializer.Deserialize(stringReader);

    Console.WriteLine("Id: " + person.Id);
    Console.WriteLine("Name: " + person.Name);
    Console.WriteLine("Street: " + person.Address.Street);

    Console.ReadLine();
}

Output for Serialization:

enter image description here

Output for Deserialization:

enter image description here


Alternative

You can also create a custom methods to read and write xml.

1) Write

public static void WriteXml(Person person, string path)
{
    using (XmlWriter writer = XmlWriter.Create(path))
    {
        //Start "struct"
        writer.WriteStartElement("struct");
        writer.WriteAttributeString("n", "People");

        writer.WriteStartElement("attr");
        writer.WriteAttributeString("n", "id");
        writer.WriteString(person.Id.ToString());
        writer.WriteEndElement();

        writer.WriteStartElement("attr");
        writer.WriteAttributeString("n", "name");
        writer.WriteString(person.Name.ToString());
        writer.WriteEndElement();

        //Start inner "struct"
        writer.WriteStartElement("struct");
        writer.WriteAttributeString("n", "Address");

        writer.WriteStartElement("attr");
        writer.WriteAttributeString("n", "street");
        writer.WriteString(person.Address.Street.ToString());
        writer.WriteEndElement();

        //End inner "struct"
        writer.WriteEndElement();

        //End "struct"
        writer.WriteEndElement();
    }
}

Usage:

Person person = new Person
{
    Id = 2,
    Name = "FIO FIO IFO",
    Address = new Address { Street = "Golden Gate" }
};

WriteXml(person, @"Path to xml file");

2) Read

public static Person ReadXml(string path)
{
    Person person = new Person();

    using (XmlReader reader = XmlReader.Create(path))
    {
        while (reader.Read())
        {
            if (reader.Name == "attr" && reader.GetAttribute("n") == "id")
                person.Id = Convert.ToInt32(reader.ReadInnerXml());

            if (reader.Name == "attr" && reader.GetAttribute("n") == "name")
                person.Name = reader.ReadInnerXml();

            if (reader.Name == "attr" && reader.GetAttribute("n") == "street")
                person.Address = new Address { Street = reader.ReadInnerXml() };
        }
    }

    return person;
}

Usage:

Person result = ReadXml(@"Path to same xml file that generated by above serializer");
Sign up to request clarification or add additional context in comments.

1 Comment

I`m combine XmlWriter and XElement with Reflection. Thx!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.