Working with XML in Silverlight and bonus – generic Property Bag implementation
I believe, that if you are in programming, you know what Property Bag is. This is handy generic class, that can "eat" poor-known structure and process a list with all this information. You often can access properties of the parent class by name.
Why this good? Property Bag provides very intuitive way to access data. This type safe collection, that has not single type, but can be filled with data of different types. Let’s see an example of such data.
<vCard> <FullName> <FamilyName>Crystal</FamilyName> <GivenName>Corky</GivenName> </FullName> <Title>Computer Officer Class 3</Title> <Role>Programmer</Role> <Phone>+61 7 555 5555</Phone> <Email>corky@qqqfoo.com</Email> <Organization> <OrganizationName>qqqfoo.com Pty Ltd</OrganizationName> <OrganizationUnit> Commercialisation Division </OrganizationUnit> </Organization> <Address> <Street>111 Lake Drive</Street> <Locality>WonderCity </Locality> <Pcode>55555</Pcode> <Country>Australia</Country> </Address> </vCard>
Well, in order to get any information from such file, you need to parse XML and know it’s structure or DTD. If someone will change the file and remove FullName tag, for example, all your program often have to be rewritten. So, we’re implementing PropertyBag helper call to take care on such cases. Here the simple implementation of such class in C#
public class PropertyBag : List<KeyValuePair<string, string>> { public PropertyBag (XmlDocument source) { //((WaitCallback)delegate //{ fillTheBag(source.ChildNodes); //}).BeginInvoke(null, null, null); } void fillTheBag(XmlNodeList root) { for (int i = 0; i < root.Count; i++) { if (root[i].ChildNodes.Count > 0) { fillTheBag(root[i].ChildNodes); } else { base.Add(new KeyValuePair<string, string>(root[i].ParentNode.Name, root[i].InnerText)); } } } public string GetPropertyValue(string property) { for (int i = 0; i < base.Count; i++) { if (base[i].Key == property) return base[i].Value; } return string.Empty; } }
Now, you can create PropertyBag by using easy constructor with XmlDocument as parameter and call any of internal information, found in source XML as bag["FirstName"].
This is very cool, but when we want to implement such approach in Silverlight, we will find, that there is no XmlDocument there, as well as no DOM at all. The only thing, you can use is XmlReader, that reads information from string stream and parses in on the fly. So how to know, when we have nested elements, how to know, that we have types of data. Let me introduce you SilverPropertyBag, useful class to read information from remote XML file and put it into property bag.
public class SilverPropertiesBag : List<KeyValuePair<string, string>> { public SilverPropertiesBag(string xmlPath) { XmlReaderSettings settings = new XmlReaderSettings(); settings.ConformanceLevel = ConformanceLevel.Fragment; settings.IgnoreWhitespace = true; settings.IgnoreComments = true; settings.IgnoreProcessingInstructions = true; try { HttpWebRequest request = new BrowserHttpWebRequest(new Uri(xmlPath)); HttpWebResponse response = request.GetResponse(); Stream content = response.GetResponseStream(); XmlReader reader = XmlReader.Create(content, settings); reader.MoveToFirstAttribute(); fillTheBag(reader); } catch {} } void fillTheBag(XmlReader root) { int depth = root.Depth; KeyValuePair<string, string> last = new KeyValuePair<string, string>(); while (root.Read()) { switch (root.NodeType) { case XmlNodeType.Text: last = new KeyValuePair<string, string>(root.Name, root.Value); break; case XmlNodeType.EndElement: if (last.Key == string.Empty && last.Value != string.Empty) { last = new KeyValuePair<string, string>(root.Name, last.Value); base.Add(last); last = new KeyValuePair<string,string>(); } if (depth > root.Depth) return; break; } if (root.IsEmptyElement || root.EOF) return; else if (root.IsStartElement()) { string name = root.Name; if (root.HasAttributes) { while (root.MoveToNextAttribute()) { base.Add(new KeyValuePair<string, string>(root.Name, root.Value)); } root.Read(); if (root.NodeType == XmlNodeType.CDATA && root.Value.Length == 0) { root.Read(); } if (root.NodeType == XmlNodeType.Text && root.ValueType == typeof(string) && root.Value != string.Empty) { base.Add(new KeyValuePair<string, string>(name, root.Value)); } if (root.NodeType == XmlNodeType.EndElement && root.Name.Equals(name)) { root.Read(); if (root.Depth < depth) return; else continue; } if (root.IsStartElement()) { if (root.Depth > depth) fillTheBag(root); else continue; } root.Read(); } } } } public string GetPropertyValue(string property) { for (int i = 0; i < base.Count; i++) { if (base[i].Key == property) return base[i].Value; } return string.Empty; } }
Well. It’s pretty easy to understand how it works, but it’s extremely useful for any of your Silverlight projects. Happy programming.
You may also be interested with:
September 3rd, 2007 · Comments (10)
10 Responses to “Working with XML in Silverlight and bonus – generic Property Bag implementation”
Leave a Reply
Discover other tags
My tools
- .NET Framework Detector
- Duplicate images finder
- Exchange Security Policy for Windows Mobile Devices Fix
- Gas Price Windows Vista SideBar gadget
- Israel Traffic Information Windows Vista SideBar gadget
- Localization fix for SAP ES Explorer for Visual Studio
- LocTester
- RTL and LTR in Windows Live Writer
- Silverlight controls library
- Snipping tool integration plugin for WLW
- USB FM receiver library
- Vista Battery Saver
- WebCam control for WPF
- Windows Live SkyDrive attachment for Windows Live Writer
- Wireless Migrator
- WPF Virtual Keyboard





January 1st, 2009 at 12:22 am
Take a look here blogs.microsoft.co.il/…/networking-raw-sockets-in-silverlight-and-wpf-messaging-in-general.aspx. As always, you can use raw sockets
January 1st, 2009 at 12:22 am
Thanks for the reply.
I tried WebRequest and WebResponse class, but it gvies same error.
January 1st, 2009 at 12:22 am
Manu, it’s HttpWebRequest/WebRequest now in SL2.0
January 1st, 2009 at 12:22 am
'System.Net.BrowserHttpWebRequest' is inaccessible due to its protection level
January 1st, 2009 at 12:22 am
Pingback from re: Working with XML in Silverlight and bonus – generic Property … | Burn Your Bonus
January 1st, 2009 at 12:22 am
Thanks a lot. You helped me much
January 1st, 2009 at 12:22 am
..was just passing by.. good work
January 1st, 2009 at 12:22 am
me like THAT!:)
January 1st, 2009 at 12:22 am
Hey Tamir,
That’s an awesome snippet man, thanks for the idea, I’m sure I’ll be using it.
March 29th, 2010 at 11:26 pm
Nice articles, but I am not clear about the point you mentioned about how to distinguish fake and real cheap louis vuitton.