0

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 Answer 1

0

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

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

2 Comments

WOW!!!!! you are super cool, this is what I want! Thank you so much!!!!!!
You can make the RowData to RowData<T> and all the associated classes generic as well. And in the generation code, use the generic parameter Book and Student. Like this - dataPacket.RowData = new RowData<Student>();

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.