Monday, December 20, 2010

C#: Clone HtmlControl

HtmlControl does not inherit ICloneable. So this method mimic's what's missing.


private HtmlControl CopyControl(HtmlControl sourceControl, Dictionary controlAttributes, string suffix)
{
Type controlType = sourceControl.GetType();
HtmlControl targetControl = (HtmlControl)controlType.InvokeMember(String.Empty, BindingFlags.CreateInstance, null, null, null);
targetControl.Attributes.Clear();
foreach (PropertyInfo propertyInfo in controlType.GetProperties())
{
if (propertyInfo.CanWrite)
{
if (propertyInfo.Name == "ID")
{
targetControl.ID = targetControl.TagName + suffix;
}
else
{
if (controlType.Name == "HtmlSelect")
{
//For HtmlSelect's, InnerText or InnerHtml can not be modified
//So ignore one, and use the other one for adding the individual items
if (propertyInfo.ToString() == "System.String InnerText")
continue;
else if (propertyInfo.ToString() == "System.String InnerHtml")
{
HtmlSelect sc = (HtmlSelect)sourceControl;
HtmlSelect tc = (HtmlSelect)targetControl;
foreach (var item in sc.Items)
{
tc.Items.Add(item.ToString());
}
}
else
{
propertyInfo.SetValue(targetControl, propertyInfo.GetValue(sourceControl, null), null);
}
}
else
{
propertyInfo.SetValue(targetControl, propertyInfo.GetValue(sourceControl, null), null);
}
}
}
}

Tuesday, December 7, 2010

C#: Transform XML using XSL

I love strings, so I am going to use all in's and out's as strings. The "reading from file" part can be taken care of in the application code... so as to reduce IO overhead in this method itself.

WARNING: By the way this only works for simple 'standalone' XSL transforms. For chained XSLs (where main XSL includes additional XSL's using the syntax) it would not work and may get an IO exception while trying to load "blah.xsl" unless that file is also present in the executing folder.

public string TransformXml(string xml, string xsl)
{
string responseXml = string.Empty;
//Read XML
TextReader iXmlReader = new StringReader(xml);
XmlTextReader iXmlText = new XmlTextReader(iXmlReader);
XPathDocument iXPathDocument = new XPathDocument(iXmlText);

//Read XSL
TextReader iXslReader = new StringReader(xsl);
XmlTextReader iXslText = new XmlTextReader(iXslReader);

//Get ready
XslTransform xslt = new XslTransform();
xslt.Load(iXslText);
StringBuilder sb = new StringBuilder();
TextWriter tw = new StringWriter(sb);

//Transform
xslt.Transform(iXPathDocument, null, tw);
responseXml = sb.ToString();

return responseXml;
}

Thursday, December 2, 2010

C#: Deserialize Xml (string) to an Object

A while back I posted an entry to be able to simply Serialize an object into Xml. Now it is time to do the reverse. Not sure if this will work for all types of complex objects but I have not received any errors so far. Of course, it would be a good idea for the calling program to cast the returned object appropriately.

public static object DeserializeXml(string xml, System.Type objectType)
{
byte[] byteArray = Encoding.ASCII.GetBytes(xml);
MemoryStream memoryStream = new MemoryStream(byteArray);
XmlSerializer xmlSerializer = new XmlSerializer(objectType);
Object obj = xmlSerializer.Deserialize(memoryStream);
memoryStream.Close();
return obj;
}