简体   繁体   中英

XmlSerializer add attribute

I have this item Class :

public class Movie
{
    public string VideoId { get; set; }
    public string Title { get; set; }
}

And i have List<Movie> of this items and i use this code to Serialize to xml file:

string fileName = index + ".xml";
string serializationFile = Path.Combine(dir, fileName);

XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;

using (var writer = XmlWriter.Create(serializationFile, settings))
{
    var serializer = new XmlSerializer(typeof(List<Movie>));
    serializer.Serialize(writer, tmpList);
}

And this is the result:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfMovie xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Movie>
    <VideoId>MyId</VideoId>
    <Title>MyTitle</Title>
  </Movie>
  <Movie>
    <VideoId>MyId1</VideoId>
    <Title>MyTitle1</Title>
  </Movie>
  <Movie>
    <VideoId>MyId2</VideoId>
    <Title>MyTitle2</Title>
  </Movie>
  <Movie>
    <VideoId>MyId3</VideoId>
    <Title>MyTitle3</Title>
  </Movie>
</ArrayOfMovie>

And it this possible to add attribute to the ArrayOfMovie node,something like this:

<ArrayOfMovie xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" customattribute='Yes'>

Yes, you can do this using the XmlAttribute attribute . In order to do this, you need to define your custom attribute. It comes with the price of one more class that represents the array (nested in the root node). If you have no problem with this addition, then the solution can look like this:

public class ArrayOfMovie
{
    // define the custom attribute
    [XmlAttribute(AttributeName="CustomAttribute")]
    public String Custom { get; set; }
    // define the collection description
    [XmlArray(ElementName="Items")]
    public List<Movie> Items { get; set; }
}

public class Movie
{
    public string VideoId { get; set; }
    public string Title { get; set; }
}

Then create, fill and serialize as you already do - the one new thing is to fill your custom attribute:

// create and fill the list
var tmpList = new List<Movie>();
tmpList.Add(new Movie { VideoId = "1", Title = "Movie 1" });
tmpList.Add(new Movie { VideoId = "2", Title = "Movie 2" });
// create the collection
var movies = new ArrayOfMovie 
            { 
                Items = tmpList, 
                Custom = "yes" // fill the custom attribute
            };
// serialize
using (var writer = XmlWriter.Create(serializationFile, settings))
{
    var serializer = new XmlSerializer(typeof(ArrayOfMovie));
    serializer.Serialize(writer, movies);
}

The XML output looks like this:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfMovie   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                CustomAttribute="yes">
  <Items>
    <Movie>
      <VideoId>1</VideoId>
      <Title>Movie 1</Title>
    </Movie>
    <Movie>
      <VideoId>2</VideoId>
      <Title>Movie 2</Title>
    </Movie>
  </Items>
</ArrayOfMovie>

You could do it after serialization. The code skeleton looks like:

    using (MemoryStream ms = new MemoryStream())
    {
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.Indent = true;

        using (var writer = XmlWriter.Create(ms, settings))
        {
            var serializer = new XmlSerializer(typeof(List<Movie>));
            serializer.Serialize(writer, tmpList);
        }

        ms.Position = 0;
        XDocument doc = XDocument.Load(new XmlTextReader(ms));
        doc.Root.Add(new XAttribute("customAttribute", "Yes"));
        doc.Save(filename);
    }

You would want to wrap the List<Movie> inside a class and then serialize that. Something like the following

class Program
{        
    static void Main(string[] args)
    {
        string fileName = "abcd2.xml";
        string serializationFile = Path.Combine(@"C:\", fileName);

        List<Movie> tmpList = new List<Movie>();
        tmpList.Add(new Movie() { VideoId = "1", Title = "Hello" });
        tmpList.Add(new Movie() { VideoId = "2", Title = "ABCD" });

        MovieList list = new MovieList("Yes", tmpList);

        XmlWriterSettings settings = new XmlWriterSettings();
        settings.Indent = true;

        using (var writer = XmlWriter.Create(serializationFile, settings))
        {
            var serializer = new XmlSerializer(typeof(MovieList));
            serializer.Serialize(writer, list);
        }
    }
}

public class MovieList
{
    private string custom;
    private List<Movie> movies;

    public MovieList() { }

    public MovieList(string custom, List<Movie> movies)
    {
        this.movies = movies;
        this.custom = custom;
    }

    [XmlAttribute]
    public string CustomAttribute
    {
        get { return this.custom; }
        set { this.custom = value; }
    }

    public List<Movie> Movies
    {
        get
        {
            return  movies;
        }
        set
        {
            this.movies = value;
        }
    }
}

public class Movie
{
    public string VideoId { get; set; }
    public string Title { get; set; }
}

The code can be improved a lot. This is just an example snippet. Check out the following MSDN link: http://msdn.microsoft.com/en-us/library/58a18dwa(v=vs.110).aspx

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