I have created a C# class:
public class books {
public int bookNum { get; set; }
public class book {
public string name { get; set; }
public class record {
public string borrowDate { get; set; }
public string returnDate { get; set; }
}
public record[] records { get; set; }
}
public book[] books { get; set; }
}
But is when I use XmlSerializer convert to XML string. The result is not the same as below xml.
What is the problem of my C# class? I want to use XmlSerializer to ouput the result instead of using XmlDocument.
Any ideas? Thanks in advance!
<books>
<bookNum>2</bookNum>
<book>
<name>Book 1</name>
<record>
<borrowDate>2013-7-1</borrowDate>
<returnDate>2013-7-12</returnDate>
</record>
<record>
<borrowDate>2013-8-1</borrowDate>
<returnDate>2013-8-5</returnDate>
</record>
</book>
<book>
<name>Book 2</name>
<record>
<borrowDate>2013-6-1</borrowDate>
<returnDate>2013-6-12</returnDate>
</record>
<record>
<borrowDate>2013-7-1</borrowDate>
<returnDate>2013-7-5</returnDate>
</record>
</book>
</books>
EDIT
Below is my C# code and the ouput result:
books books = new books {
bookNum = 2,
Books = new books.book[] {
new books.book {
name = "Book1",
records = new books.book.record[] {
new books.book.record {
borrowDate = "2013-1-3",
returnDate = "2013-1-5"
},
new books.book.record {
borrowDate = "2013-2-3",
returnDate = "2013-4-5"
}
}
},
new books.book {
name = "Book1",
records = new books.book.record[] {
new books.book.record {
borrowDate = "2013-1-3",
returnDate = "2013-1-5"
},
new books.book.record {
borrowDate = "2013-2-3",
returnDate = "2013-4-5"
}
}
}
}
};
XmlSerializer xsSubmit = new XmlSerializer(typeof(books));
XmlDocument doc = new XmlDocument();
System.IO.StringWriter sww = new System.IO.StringWriter();
XmlWriter writer = XmlWriter.Create(sww);
xsSubmit.Serialize(writer, books);
var xml = sww.ToString(); // Your xml
context.Response.Write(xml);
XML:
<books>
<bookNum>2</bookNum>
<Books>
<book>
<name>Book1</name>
<records>
<record>
<borrowDate>2013-1-3</borrowDate>
<returnDate>2013-1-5</returnDate>
</record>
<record>
<borrowDate>2013-2-3</borrowDate>
<returnDate>2013-4-5</returnDate>
</record>
</records>
</book>
<book>
<name>Book1</name>
<records>
<record>
<borrowDate>2013-1-3</borrowDate>
<returnDate>2013-1-5</returnDate>
</record>
<record>
<borrowDate>2013-2-3</borrowDate>
<returnDate>2013-4-5</returnDate>
</record>
</records>
</book>
</Books>
</books>
You cannot serialize class from your question using standard serialization tools so that it will have <book>
entries on the same level as <bookNum>
node.
When class saved with standard serialization tools list of your <book>
nodes will always be nested into separate array node that will be on the same level as <bookNum>
node. Same concerns records
array field on book
class.
To generate XML output that you want to - with <book>
nodes on same level as <bookNum>
node - you will have to implement IXmlSerializable interface in your books
class for custom serialization. To see examples of IXmlSerializable
implementation visit these links: StackOverflow answer, CodeProject article.
Another solution will be - as stated user Alexandr in comment to my answer - to inherit your books
class from List<book>
type and to have on your book
class field records
of class type that is inherited from List<record>
type.
When serializing class from your question, assuming that your assigned proper XmlRoot, XmlElement, XmlArray and XmlArrayItem attributes as follows:
[XmlRoot("books")]
public class books
{
[XmlElement("bookNum")]
public int bookNum { get; set; }
[XmlRoot("book")]
public class book
{
[XmlElement("name")]
public string name { get; set; }
[XmlRoot("record")]
public class record
{
[XmlElement("borrowDate")]
public string borrowDate { get; set; }
[XmlElement("returnDate")]
public string returnDate { get; set; }
}
[XmlArray("borrowRecords")]
[XmlArrayItem("record")]
public record[] records { get; set; }
}
[XmlArray("booksList")]
[XmlArrayItem("book")]
public book[] books { get; set; }
}
you will get XML output as follows:
<books>
<bookNum>2</bookNum>
<booksList>
<book>
<name>Book 1</name>
<borrowRecords>
<record>
<borrowDate>2013-1-3</borrowDate>
<returnDate>2013-1-5</returnDate>
</record>
<record>
<borrowDate>2013-2-3</borrowDate>
<returnDate>2013-4-5</returnDate>
</record>
</borrowRecords>
</book>
<book>
<name>Book 2</name>
<borrowRecords>
<record>
<borrowDate>2013-1-3</borrowDate>
<returnDate>2013-1-5</returnDate>
</record>
<record>
<borrowDate>2013-2-3</borrowDate>
<returnDate>2013-4-5</returnDate>
</record>
</borrowRecords>
</book>
</booksList>
</books>
I made the following change to your class code. I am unable to duplicate the XML serialization using the default serializer, because it will not duplicate the 'Record' element without giving it a container element.
[System.Xml.Serialization.XmlRoot("books")]
public class books
{
public int bookNum { get; set; }
public class book {
public string name { get; set; }
public class record {
public string borrowDate { get; set; }
public string returnDate { get; set; }
}
public record[] records { get; set; }
}
public book[] books { get; set; }
}
Serializing this gives me the following output
<books xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<bookNum>2</bookNum>
<books>
<book>
<name>first</name>
<records>
<record>
<borrowDate>19/07/2013 4:41:29 PM</borrowDate>
<returnDate>19/07/2013 4:41:29 PM</returnDate>
</record>
</records>
</book>
</books>
</books>
using this test code
books bks = new books();
bks.bookNum = 2;
bks.books = new books.book[]{ new books.book{name="first", records = new books.book.record[] {new books.book.record{borrowDate = DateTime.Now.ToString(), returnDate = DateTime.Now.ToString()}}}};
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(books));
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = new UnicodeEncoding(false, false); // no BOM in a .NET string
settings.Indent = true;
settings.OmitXmlDeclaration = true;
using(StringWriter textWriter = new StringWriter()) {
using(XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings)) {
serializer.Serialize(xmlWriter, bks);
}
return textWriter.ToString(); //This is the output as a string
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With