2

I want to serialize/deserialize xml document in C# like:

<library>
    <my.books genre =""classic"">
         <book title = ""1984"" author=""George Orwell"" />
         <book title = ""Robinson Crusoe"" author=""Daniel Defoe"" />
         <book title = ""Frankenstein"" author=""Mary Shelly"" />
    </my.books>
</library>";

There are 2 important things:

  • Element "my.books" must have custom name (not a property name)

  • my.books element must have an attribute ("genre").

Here is my code (sample is on https://dotnetfiddle.net/bH5WVX) :

   using System;
   using System.Xml;
   using System.Xml.Linq;
   using System.Collections.Generic;
   using System.ComponentModel;
   using System.Xml.Serialization;
   using System.IO;

   public class Program
   {
    public static void Main()
    {

        Library lib = new Library(myBooks: new MyBooks(
            genre: "classic",
            booklist: new List<Book>{
                new Book("1984", "George Orwell"),
                new Book("Robinson Crusoe", "Daniel Defoe"),
                new Book("Oliver Twist", "Mary Shelly"),

            }));


          XmlSerializer formatter = new XmlSerializer(typeof(Library));

            using (StringWriter sw = new StringWriter())
            {
                formatter.Serialize(sw, lib);
                Console.Write(sw.ToString());
            }

        string desiredOutput =
                @"<library>

                    <my.books genre =""classic"">
                        <book title = ""1984"" author=""George Orwell"" />
                        <book title = ""Robinson Crusoe"" author=""Daniel Defoe"" />
                        <book title = ""Frankenstein"" author=""Mary Shelly"" />
                    </my.books>

                </library>";            
    }


[XmlRoot("library")]    
public class Library
        {
        public MyBooks MyBooks { get; set; }

        [XmlElement("my.books")] 
        public List<Book> Books { get; set; }

        public Library()
    {

    }

    public Library(MyBooks myBooks = null)
    {
        MyBooks = myBooks;
    }
}


[XmlType("my.books")]
public class MyBooks
{
     [XmlAttribute("genre")]
        public string Genre { get; set; }

     [XmlElement("book")]
        public List<Book> Booklist { get; set; }

      public MyBooks(string genre, List<Book> booklist = null)
        {
            Genre = genre;
            Booklist = booklist;
        }

          public MyBooks()
        {

        }   
}   

public class Book
    {
        [XmlAttribute("title")]
        public string Title { get; set; }
        [XmlAttribute("author")]
        public string Author { get; set; }

        public Book() { }

        public Book(string title, string author)
        {
        Title = title;
        Author = author;    
        }
    }
}

And the output is:

<library>
  <MyBooks genre="classic">
    <book title="1984" author="George Orwell" />
    <book title="Robinson Crusoe" author="Daniel Defoe" />
    <book title="Oliver Twist" author="Mary Shelly" />
  </MyBooks>
</library>

The only problem is that I can't force element "MyBooks" to use name "my.books"

I found only one related article on this topic - http://www.codemeit.com/xml/c-xmlserializer-add-an-attribute-to-an-array-element.html, it suggests to use "XmlType" attribute on class, but it doesn't work here.

Is there any way to apply custom name attribute on this element?

1
  • I have no choice, by some reason the xml configuration I work with has such element names. It's a legacy product configuration, and I can't modify it, but I need to serialize it... Commented Apr 20, 2018 at 0:22

1 Answer 1

1

It looks like your attribute was on the wrong property.

Try this:

[System.Xml.Serialization.XmlElement("my.books")]
public MyBooks MyBooks { get; set; }

public List<Book> Books { get; set; }

I now get this output:

<?xml version="1.0" encoding="utf-16"?>
<library xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <my.books genre="classic">
    <book title="1984" author="George Orwell" />
    <book title="Robinson Crusoe" author="Daniel Defoe" />
    <book title="Oliver Twist" author="Mary Shelly" />
  </my.books>
</library>

Well done on a superbly written question!

Sign up to request clarification or add additional context in comments.

1 Comment

Wow, thanks to your eyes! I spent a whole day and couldn't find this my blunder. You've saved my another day :)

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.