A Dynamic XML Document – Part 2


Continuing on from last post, how do we get the array-style [notation] on a dynamic object? Well, there’s a handy method that you can override on DynamicObject called TryGetIndex which does just that:
 
   1: /// <summary>

   2: /// Searches for any elements that have any attribute with the value specified.

   3: /// </summary>

   4: /// <param name="binder"></param>

   5: /// <param name="indexes"></param>

   6: /// <param name="result"></param>

   7: /// <returns></returns>

   8: public override bool TryGetIndex (GetIndexBinder binder, object[] indexes, out object result)

   9: {

  10:     var valueToSearchFor = indexes[0].ToString();

  11:     var matchingItems = GetElementsByAttributeValue (valueToSearchFor);

  12:     if (matchingItems.Any ())

  13:     {

  14:         result = new DynamicXmlDocument (matchingItems);

  15:         return true;

  16:     }

  17:  

  18:     result = null;

  19:     return false;

  20: }

  21:  

  22: private IEnumerable<XElement> GetElementsByAttributeValue (string attributeValue)

  23: {

  24:     var matchingItems = elements.Where (e => e.Attributes ().Any (att => att.Value == attributeValue));

  25:     return matchingItems;

  26: }

 

Here, I’m searching for any elements that have any attributes with a value as per specified, and then setting the result to a new dynamic xml document based on that sequence.

That’s really it, to be honest! The only things left are the Value getter, which just returns the value of the first element in the dxd, and the implementations of IEnumerable and IEnumerable <T>: –

   1: /// <summary>

   2: /// Gets the contents of the first element in this document.

   3: /// </summary>

   4: public string Value

   5: {

   6:     get { return elements.First ().Value; }

   7: }

   8:  

   9: IEnumerator<DynamicXmlDocument> IEnumerable<DynamicXmlDocument>.GetEnumerator ()

  10: {

  11:     foreach (var element in this.elements)

  12:         yield return new DynamicXmlDocument (element);

  13: }

  14:  

  15: IEnumerator IEnumerable.GetEnumerator ()

  16: {

  17:     foreach (var element in this.elements)

  18:         yield return new DynamicXmlDocument (element);

  19: }

 

I’m not that used to using the yield keyword – to be honest most collections I use day-to-day are the in-built IEnumerable<T> ones, but I see how it’s being used above (this bit is basically taken from here.

Anyway… the point being that with a relatively little amount of effort we have an object which can navigate an XML document very easily and more readably than old-style XML access, and with no real loss of type safety compared to those technologies, either.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s