Tuesday, June 5, 2012

XML

So you want to use XML in your application?


What should you use? there are XmlDocument, XDocument, XmlReader? XmlWriter? Help!


Lets make some order in this mess. 


What do you need to do? 


Are your XML files very big? use XmlReader/XmlWriter, but you'll have to write more code than the other options, think of it as reading a text file with a little help.


Are you used to XPath and pressed for time? you can use XmlDocument, it might make your life easy, just remember its impossible to serialize XmlDocuments.


Do you like LINQ? use XDocument/XElements, they are also serializable so its a good option if you're using WCF and need to pass XML elements.


Personally I prefer XDocument/XElement, I can serialize them when I need to, I'm used to LINQ queries so its very easy for me to query XML documents and it supports explicit casting so I don't need to deal with the whole primitive to string and back conversions.


You can find the demo project at:
https://github.com/drorgl/ForBlog/tree/master/XmlDemo


And you can't really look at these without doing some benchmarking, you may see it in the project code, but I'll just give you the highlights, XmlReader/XmlWriter are the fastest, then XDocument and last is XmlDocument.




I've included some extensions which helped me in the past with XML documents containing enums and byte arrays (or binary data):



/// <summary>
/// Converts XAttribute to enum
/// </summary>
/// <typeparam name="T">Enum type</typeparam>
/// <param name="xattribute">XAttribute object</param>
/// <param name="defaultValue">return this value if conversion fails</param>
/// <returns>defaultValur or converted enum value</returns>
public static T ToEnum<T>(this XAttribute xattribute, Enum defaultValue) where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
        throw new ArgumentException("T must be an enum");

    return (T)((xattribute == null || (string.IsNullOrEmpty(xattribute.Value))) ? defaultValue : Enum.Parse(typeof(T), xattribute.Value));
}

/// <summary>
/// Converts XElement to enum
/// </summary>
/// <typeparam name="T">Enum type</typeparam>
/// <param name="xelement">XElement object</param>
/// <param name="defaultValue">return this value if conversion fails</param>
/// <returns>defaultValur or converted enum value</returns>
public static T ToEnum<T>(this XElement xelement, Enum defaultValue) where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
        throw new ArgumentException("T must be an enum");

    return (T)((xelement == null || (string.IsNullOrEmpty(xelement.Value)))  ? defaultValue : Enum.Parse(typeof(T), xelement.Value));
}

/// <summary>
/// Converts XAttibute's value to byte array from base64 encoded string
/// </summary>
/// <param name="xattribute">XAttribute object</param>
/// <returns>byte array if successful, null if not</returns>
public static byte[] ToByteArray(this XAttribute xattribute)
{
    if (string.IsNullOrEmpty(xattribute.Value))
        return null;

    return Convert.FromBase64String(xattribute.Value);
}

/// <summary>
/// Converts XElement's value to byte array from base64 encoded string
/// </summary>
/// <param name="xelement">XElement object</param>
/// <returns>byte array if successful, null if not</returns>
public static byte[] ToByteArray(this XElement xelement)
{
    if (string.IsNullOrEmpty(xelement.Value))
        return null;

    return Convert.FromBase64String(xelement.Value);
}










No comments:

Post a Comment