How to export/generate XML file with METADATA in ASP.NET Core using C#?

752 views Asked by At

I need to get data from database, massage it into list of objects, then finally generate an XML file with a METADATA tag (expected result), I think those DATA PACKET, METADATA, etc.. tag is not manually written it, maybe there is some library in ASP.NET Core using C# able to generate it automatically when serializing the data into XML?

Here is the code I tried out, it didn't turns out to expected result as I need it.

    public class Book
    {
        public string title;
        public string author;
        public string publisher;
        public double price;
    }
  
    public void GenerateXML()
    {
       var overview = new List<Book>{
            new Book()
            {
                title = "This is a book",
                author = "Somebody wrote it",
                publisher = "Someone published it",
                price = 999.99
            },
            new Book()
            {
                title = "This is a book2",
                author = "Somebody wrote it2",
                publisher = "Someone published it2",
                price = 101010
            }
        };

        System.Xml.Serialization.XmlSerializer writer = new System.Xml.Serialization.XmlSerializer(typeof(Book));

        var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "//myXmFile.xml";
        System.IO.FileStream file = System.IO.File.Create(path);

        foreach (var item in overview)
        {
            writer.Serialize(file, item);
        }

        file.Close();
    }

This code produces:

<?xml version="1.0" encoding="utf-8"?>
<Book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <title>
        This is a book
    </title>
    <author>
        Somebody wrote it
    </author>
    <publisher>
        Someone published it
    </publisher>
    <price>
        999.99
    </price>
</Book>
<?xml version="1.0" encoding="utf-8"?>
<Book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <title>
        This is a book2
    </title>
    <author>
        Somebody wrote it2
    </author>
    <publisher>
        Someone published it2
    </publisher>
    <price>
        101010
    </price>
</Book>

Expected result:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>  
<DATAPACKET Version="2.0">
    <METADATA>
            <FIELDS>
                <FIELD attrname="title" fieldtype="string"/>
                <FIELD attrname="author" fieldtype="string"/>
                <FIELD attrname="publisher" fieldtype="string"/>
                <FIELD attrname="price" fieldtype="r8"/>
            </FIELDS>
        <PARAMS/>
    </METADATA>
    
    <ROWDATA>
        <ROW title="This is a book" author="Somebody wrote it" publisher="Someone published it" price="999.99" />
        <ROW title="This is a book2" author="Somebody wrote it2" publisher="Someone published it2" price="101010" />
    </ROWDATA>
</DATAPACKET>

Is there any library in ASP.NET Core / C# able to generate this expected result?

1

There are 1 answers

2
Anuraj On BEST ANSWER

Here is the code. I generated the class using https://xmltocsharp.azurewebsites.net/

Generated class.

[XmlRoot(ElementName = "FIELD")]
public class Field
{
    [XmlAttribute(AttributeName = "attrname")]
    public string Attrname { get; set; }
    [XmlAttribute(AttributeName = "fieldtype")]
    public string Fieldtype { get; set; }
}

[XmlRoot(ElementName = "FIELDS")]
public class Fields
{
    [XmlElement(ElementName = "FIELD")]
    public List<Field> Field { get; set; }
}

[XmlRoot(ElementName = "METADATA")]
public class MetaData
{
    [XmlElement(ElementName = "FIELDS")]
    public Fields Fields { get; set; }
    [XmlElement(ElementName = "PARAMS")]
    public string Params { get; set; }
}

[XmlRoot(ElementName = "ROW")]
public class Book
{
    [XmlAttribute(AttributeName = "title")]
    public string Title { get; set; }
    [XmlAttribute(AttributeName = "author")]
    public string Author { get; set; }
    [XmlAttribute(AttributeName = "publisher")]
    public string Publisher { get; set; }
    [XmlAttribute(AttributeName = "price")]
    public string Price { get; set; }
}

[XmlRoot(ElementName = "ROW")]
public class Student
{
    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }
    [XmlAttribute(AttributeName = "age")]
    public int Age { get; set; }
}

[XmlRoot(ElementName = "ROWDATA")]
public class RowData<T>
{
    [XmlElement(ElementName = "ROW")]
    public List<T> Row { get; set; }
}

[XmlRoot(ElementName = "DATAPACKET")]
public class DataPacket<T>
{
    [XmlElement(ElementName = "METADATA")]
    public MetaData MetaData { get; set; }
    [XmlElement(ElementName = "ROWDATA")]
    public RowData<T> RowData { get; set; }
    [XmlAttribute(AttributeName = "Version")]
    public string Version { get; set; }
}

I modified the generated code a little bit.

And here is the XML generation logic.

public IActionResult GenerateXmlStudent()
{
    var dataPacket = new DataPacket<Student>();
    dataPacket.MetaData = new MetaData();
    dataPacket.MetaData.Fields = new Fields();
    dataPacket.MetaData.Fields.Field = new List<Field>();
    dataPacket.MetaData.Fields.Field.Add(new Field { Attrname = "name", Fieldtype = "string" });
    dataPacket.MetaData.Fields.Field.Add(new Field { Attrname = "age", Fieldtype = "int" });
    dataPacket.MetaData.Params = "name,age";
    dataPacket.RowData = new RowData<Student>();
    dataPacket.RowData.Row = new List<Student>();
    dataPacket.RowData.Row.Add(new Student { Name = "Student1", Age = 20 });
    dataPacket.RowData.Row.Add(new Student { Name = "Student2", Age = 20 });
    dataPacket.RowData.Row.Add(new Student { Name = "Student3", Age = 20 });
    dataPacket.RowData.Row.Add(new Student { Name = "Student4", Age = 20 });
    var xmlSerializer = new XmlSerializer(typeof(DataPacket<Student>));
    using var stringWriter = new StringWriter();
    xmlSerializer.Serialize(stringWriter, dataPacket);
    var xml = stringWriter.ToString();
    return Content(xml, "text/xml");
}

And the other class.

public IActionResult GenerateXmlBook()
{
    var dataPacket = new DataPacket<Book>();
    dataPacket.MetaData = new MetaData();
    dataPacket.MetaData.Fields = new Fields();
    dataPacket.MetaData.Fields.Field = new List<Field>();
    dataPacket.MetaData.Fields.Field.Add(new Field { Attrname = "title", Fieldtype = "string" });
    dataPacket.MetaData.Fields.Field.Add(new Field { Attrname = "author", Fieldtype = "string" });
    dataPacket.MetaData.Fields.Field.Add(new Field { Attrname = "publisher", Fieldtype = "string" });
    dataPacket.MetaData.Fields.Field.Add(new Field { Attrname = "price", Fieldtype = "string" });
    dataPacket.MetaData.Params = "title,author,publisher,price";
    dataPacket.RowData = new RowData<Book>();
    dataPacket.RowData.Row = new List<Book>();
    dataPacket.RowData.Row.Add(new Book { Title = "The Hobbit", Author = "J.R.R. Tolkien", Publisher = "Houghton Mifflin", Price = "29.99" });
    dataPacket.RowData.Row.Add(new Book { Title = "Harry Potter and the Sorcerer's Stone", Author = "J.K. Rowling", Publisher = "Scholastic", Price = "29.99" });
    dataPacket.RowData.Row.Add(new Book { Title = "The Lord of the Rings", Author = "J.R.R. Tolkien", Publisher = "Houghton Mifflin", Price = "29.99" });
    dataPacket.RowData.Row.Add(new Book { Title = "The Da Vinci Code", Author = "Dan Brown", Publisher = "Doubleday", Price = "29.99" });
    var xmlSerializer = new XmlSerializer(typeof(DataPacket<Book>));
    using var stringWriter = new StringWriter();
    xmlSerializer.Serialize(stringWriter, dataPacket);
    var xml = stringWriter.ToString();
    return Content(xml, "text/xml");
}

And here is the screenshot.

Generated XML