Reputation: 11252
I have a class with four fields (DateTime, Enum, string, string). I want to serialize it to and from an XML element or a series of XML elements in a compact manner. For example, I might serialize it to something like this:
<i t='234233' a='3'><u>Username1</u><s1>This is a string</s1></i>
<i t='234233' a='4'><u>Username2</u><s1>This is a string</s1></i>
<i t='223411' a='1'><u>Username3</u><s1>This is a string</s1></i>
Where 'i' is each class instance, 't' is the DateTime ticks, 'a' is the enum value, and the elements are strings.
I'd prefer to not have a root element, but if I do have it, I'd like it to be as small as possible.
I've tried using XmlSerializer with the XmlWriterSettings class but I can't get rid of the namespaces and root element.
What's the best way of doing this? I'm not saving to a file, I'm reading and writing to strings in memory.
Upvotes: 1
Views: 1034
Reputation: 727077
If your data is that simple, you can use XmlWriter
directly:
class Data {
public DateTime Date { get; set; }
public int Code { get; set; }
public string First { get; set; }
public string Last { get; set; }
}
static void Main() {
var sb = new StringBuilder();
var xws = new XmlWriterSettings();
xws.OmitXmlDeclaration = true;
xws.Indent = false;
var elements = new[] {
new Data { Date = DateTime.Now, First = "Hello", Last = "World", Code = 2}
, new Data { Date = DateTime.UtcNow, First = "Quick", Last = "Brown", Code = 4}
};
using (var xw = XmlWriter.Create(sb, xws)) {
xw.WriteStartElement("root");
foreach (var d in elements) {
xw.WriteStartElement("i");
xw.WriteAttributeString("t", ""+d.Date);
xw.WriteAttributeString("a", "" + d.Code);
xw.WriteElementString("u", d.First);
xw.WriteElementString("s1", d.Last);
xw.WriteEndElement();
}
xw.WriteEndElement();
}
Console.WriteLine(sb.ToString());
}
Running this program produces the following output (I added line breaks for clarity; they are not in the output):
<root>
<i t="2/9/2012 3:16:56 PM" a="2"><u>Hello</u><s1>World</s1></i>
<i t="2/9/2012 8:16:56 PM" a="4"><u>Quick</u><s1>Brown</s1></i>
</root>
You need that root element if you would like to read the information back. The most expedient way would be using LINQ2XML:
var xdoc = XDocument.Load(new StringReader(xml));
var back = xdoc.Element("root").Elements("i").Select(
e => new Data {
Date = DateTime.Parse(e.Attribute("t").Value)
, Code = int.Parse(e.Attribute("a").Value)
, First = e.Element("u").Value
, Last = e.Element("s1").Value
}
).ToList();
Upvotes: 1
Reputation: 116188
System.Xml.Linq
XElement xElem = new XElement("r");
for (int i = 0; i < 3; i++)
{
xElem.Add(
new XElement("i",
new XAttribute("t", "234233"),
new XAttribute("a", "3"),
new XElement("u", "UserName"),
new XElement("s1", "This is a string")
)
);
}
var str = xElem.ToString();
and to read
XElement xElem2 = XElement.Load(new StringReader(str));
foreach(var item in xElem2.Descendants("i"))
{
Console.WriteLine(item.Attribute("t").Value + " " + item.Element("u").Value);
}
PS:
You don't need to convert xElem
to string in order to use that xml in memory
Upvotes: 2
Reputation: 19621
You'll need to implement your own serializer, I believe, which will be a pain. That, or you could manually strip out what you don't need after serializing, which could work.
If size is your concern, you should be serializing to binary using BinaryFormatter
. You can always base-64 encode it if you need to store it as a string. (BinaryFormatter
works almost just like XmlSerializer
, except the output is raw binary, rather than nicely formatted XML.)
Upvotes: 0
Reputation: 12157
I'd just use a StringBuilder
, personally.
If size is your #1 concern, consider json
or yaml
instead of XML.
Upvotes: 0