Quantcast
Channel: General .NET – Brian Pedersen's Sitecore and .NET Blog
Viewing all articles
Browse latest Browse all 167

XElement get default values using extension methods

$
0
0

I often work with dynamic XML documents which might or might not contain the element, field or attribute that I am looking for. The Standard .NET XElement class is pretty strict (as it should be) and returns a null reference execption if you ask for the value of an element that is not there:

<employees>
 <employee id="bp">
   <name>Brian</name>
 </employee>
 <employee id="ap">
   <name>Anita</name>
   <position>CEO</position>
 </employee>
</employees>

In the example above I can look for the position element for employee AP, but not for employee BP. Instead of building my exception handling every time I ask for the position element, I have built a set of extension methods that take care of this.

Extension methods 1 and 2: SafeValue and SafeAttribute

The following methods allows me to return a default value if the value of either an element or an attribute is not present:

using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace MyCode.Extensions
{
  public static class XElementExtension
  {
     public static string SafeValue(this XElement element, string defaultValue)
     {
       if (element == null)
         return defaultValue;
       if (element.Value == null)
         return defaultValue;
       return element.Value;
     }

     public static string SafeAttribute(this XElement element, XName name, string defaultValue)
     {
       if (element == null)
         return defaultValue;
       if (element.Attribute(name) == null)
         return defaultValue;
       if (element.Attribute(name).Value == null)
         return defaultValue;
       return element.Attribute(name).Value;
     }
  }
}

Extensions 3 and 4: GetElementFromPath and GetValueFrompath

These extensions are more exotic. They allow me to ask for an element or a value down a path from the current element, returning a default value if the element or value is not present:

public static XElement GetElementFromPath(this XElement element, params string[] path)
{
  if (element == null)
    return null;

  XElement current = element;
  foreach (string s in path)
  {
    if (current != null && current.Element(s) != null)
      current = current.Element(s);
  }
  return current;
}

public static string GetValueFromPath(this XElement element, params string[] path)
{
  if (element == null)
    return string.Empty;

  XElement current = element;
  foreach (string s in path)
  {
    if (current != null && current.Element(s) != null)
      current = current.Element(s);
  }
  return current != null ? current.Value : "";
}

The functions might seem strange, but it’s cool to be able to do this:

element.GetValueFromPath("employee", "position");

Extension 5: Convert XElement to XmlElement

The last extension method is a old goodie. Converting from the LINQ based XElement to the old-fashioned XmlElement class is handy when working with web services or other methods that requires the old XmlElement.

    public static XmlElement ToXmlElement(this XElement element)
    {
      return new XmlService(element).CreateXmlElement();
    }

    #region internal conversion class

    internal class XmlService
    {
      private readonly StringBuilder _sb;
      private readonly XmlWriter _writer;

      private XmlService()
      {
        _sb = new StringBuilder();
        _writer = new XmlTextWriter(new StringWriter(_sb))
        {
          Formatting = Formatting.Indented,
          Indentation = 2
        };
      }

      public XmlService(XNode e) : this()
      {
        e.WriteTo(_writer);
      }

      public XmlService(XmlNode e) : this()
      {
        e.WriteTo(_writer);
      }

      public XElement CreateXElement()
      {
        return XElement.Load(new StringReader(_sb.ToString()));
      }

      public XDocument CreateXDocument()
      {
        return XDocument.Load(new StringReader(_sb.ToString()));
      }

      public XmlElement CreateXmlElement()
      {
        return CreateXmlDocument().DocumentElement;
      }

      public XmlDocument CreateXmlDocument()
      {
        var doc = new XmlDocument();
        doc.Load(new XmlTextReader(new StringReader(_sb.ToString())));
        return doc;
      }
    }
    #endregion


Viewing all articles
Browse latest Browse all 167

Latest Images

Trending Articles



Latest Images