Thursday, February 14, 2008

How to remove whitespace from xml serialized from a custom object

Recently I came across a problem with whitespace in xml that I was serializing from a custom entity class. The situation is this – I create my custom object, apply the XmlSerializer to it, generate the xml and put it in a memory stream without a hitch. I then convert to a string and save to a database. While verifying the data being saved I find that about %30 of the xml is whitespace, which can become quite considerable when you take into account hundreds of thousands of transactions. My first thought was to use good old regular expressions, but I was concerned about unintentionally removing whitespace that I may want to keep – such as inside an element or attribute. What I finally came up with was to load the xml string into an XmlDocument and set the PreserveWhitespace to false. See below for a simplified example.

Create and populate a custom object:

Car c = new Car();

c.Make = "Jeep";

c.Model = "Wrangler";

c.Year = "1981";


Use the XmlSerializer class to serialize the object as xml to a System.IO.MemoryStream:

System.IO.MemoryStream ms = new System.IO.MemoryStream();

System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(c.GetType());

xs.Serialize(ms, c);


Convert to string for storage in database or other use:


string str = System.Text.ASCIIEncoding.ASCII.GetString(ms.ToArray());


You will now have the following xml in your string variable (it actually has tabs too, but when publishing from Word, blogspot doesn't render the html quite as I expected) So this is nice, right?

<?xml version="1.0"?>

<Car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<Make>Jeep</Make>

<Model>Wrangler</Model>

<Year>1981</Year>

</Car>


Yes and no. The XmlSerializer class is very useful in that it is easy to implement, but it includes whitespace by default. This is good for presentation, but bad for data storage and transmission. The easiest way I have found to strip the white space is to do the following:

Create an XmlDocument and load the string into it:

System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();

xmlDoc.LoadXml(str);


Then set the PreserveWhitespace property to false:

xmlDoc.PreserveWhitespace = false;


Now the .OuterXml property of the XmlDocument will have this:

<?xml version="1.0"?><Car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Make>Jeep</Make><Model>Wrangler</Model><Year>1981</Year></Car>

All done! Xml without the whitespace!

7 comments:

Anonymous said...

Awesome dude! Thanks :)

Anonymous said...

Try this:

public static string ToXmlString(this object value)
{

XmlSerializer serializer = new XmlSerializer(value.GetType(), "");
XmlWriterSettings ws = new XmlWriterSettings();
StringBuilder stringBuilder = new StringBuilder();
using (XmlWriter xmlWriter = XmlWriter.Create(stringBuilder, ws))
{
try
{
serializer.Serialize(xmlWriter, value, null);
}
// An error occurred during serialization. The original exception is available
// using the System.Exception.InnerException property. Ignore this and return null.
catch (InvalidOperationException)
{
return null;
}

return stringBuilder.ToString();
}
}

Anonymous said...

Very helpful, thanks!

Anonymous said...

top [url=http://www.c-online-casino.co.uk/]casino online[/url] brake the latest [url=http://www.realcazinoz.com/]casino[/url] manumitted no set aside perk at the chief [url=http://www.baywatchcasino.com/]bay take note of casino
[/url].

Anonymous said...

Why create xmldocument which is a waste of memory and resources?

XmlSerializer can do it out of the box

var s = new XmlWriterSettings();
s.NewLineHandling = NewLineHandling.None;
s.Indent = false;
using (var file2 = File.OpenWrite("myfile.xml"))
using (var xmlWriter = XmlWriter.Create(file2, s))
{
ser.Serialize(xmlWriter, communiation);

}

Anonymous said...

7a replica bags wholesale Bonuses j9o28n3d17 replica bags china free shipping replica bags for sale hermes replica handbags g6r93e3p28 replica bags pakistan find more info m5g21d1b02 replica ysl replica bags hong kong

toute said...

a1s60w4w92 z1x41n3u28 i9m82u4e13 b5h27c0m09 r8i95o4p43 k4s05w6r14