Created
September 6, 2012 08:43
-
-
Save markrendle/3653184 to your computer and use it in GitHub Desktop.
Utility classes for dealing with XML as Dictionaries
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Simple.NExtLib.Xml | |
{ | |
public class XmlAttributesAsDictionary | |
{ | |
private readonly XElement _element; | |
public XmlAttributesAsDictionary(XElement element) | |
{ | |
_element = element; | |
} | |
public string this[string name] | |
{ | |
get | |
{ | |
var attr = _element.Attribute(_element.ResolveName(name)) ?? _element.Attribute(name); | |
if (attr == null) return null; | |
return attr.Value; | |
} | |
set | |
{ | |
var xname = _element.ResolveName(name); | |
var attr = _element.Attribute(xname); | |
if (attr == null) | |
{ | |
_element.Add(new XAttribute(xname, value)); | |
} | |
else | |
{ | |
attr.Value = value; | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Simple.NExtLib.Xml | |
{ | |
public class XmlElementAsDictionary | |
{ | |
private readonly XElement _element; | |
public XmlElementAsDictionary(string name) | |
{ | |
_element = new XElement(name); | |
} | |
public XmlElementAsDictionary(string name, string defaultNamespace) | |
{ | |
_element = XElement.Parse(string.Format(@"<{0} xmlns{1}=""{2}""/>", name, GetPrefixPart(name), defaultNamespace)); | |
} | |
public XmlElementAsDictionary(XElement element) | |
{ | |
_element = element; | |
} | |
public XmlElementAsDictionary this[string name] | |
{ | |
get | |
{ | |
var xname = _element.ResolveName(name); | |
return new XmlElementAsDictionary(_element.Element(xname) ?? CreateElement(xname)); | |
} | |
} | |
public IEnumerable<string> Keys | |
{ | |
get { return _element.Elements().Select(element => _element.FormatName(element.Name)); } | |
} | |
public string Value | |
{ | |
get | |
{ | |
return _element.Value; | |
} | |
set | |
{ | |
_element.Value = value; | |
} | |
} | |
public void Clear() | |
{ | |
_element.RemoveAll(); | |
} | |
public int Count | |
{ | |
get { return _element.Elements().Count(); } | |
} | |
private XElement CreateElement(XName name) | |
{ | |
var element = new XElement(name); | |
_element.Add(element); | |
return element; | |
} | |
public override string ToString() | |
{ | |
return _element.ToString(); | |
} | |
public void AddPrefixedNamespace(string prefix, string @namespace) | |
{ | |
_element.Add(new XAttribute(XNamespace.Xmlns + prefix, @namespace)); | |
} | |
public XmlAttributesAsDictionary Attributes | |
{ | |
get { return new XmlAttributesAsDictionary(_element); } | |
} | |
public XElement ToElement() | |
{ | |
return new XElement(_element); | |
} | |
public XDocument ToDocument() | |
{ | |
return new XDocument(_element); | |
} | |
public XDocument ToDocument(XDeclaration declaration) | |
{ | |
return new XDocument(declaration, _element); | |
} | |
public bool ContainsKey(string name) | |
{ | |
return ContainsKey(_element.ResolveName(name)); | |
} | |
private bool ContainsKey(XName name) | |
{ | |
return _element.Elements(name).Any(); | |
} | |
public bool Remove(string name) | |
{ | |
return Remove(_element.ResolveName(name)); | |
} | |
private bool Remove(XName name) | |
{ | |
var elementToRemove = _element.Element(name); | |
if (elementToRemove == null) return false; | |
elementToRemove.Remove(); | |
return true; | |
} | |
private static string GetPrefixPart(string name) | |
{ | |
if (name.Contains(':')) | |
{ | |
var bits = name.Split(':'); | |
if (bits.Length != 2) throw new ArgumentException("name"); | |
return ":" + bits[0]; | |
} | |
return ""; | |
} | |
public static XmlElementAsDictionary Parse(string text) | |
{ | |
if (text == null) throw new ArgumentNullException("text"); | |
return new XmlElementAsDictionary(XElement.Parse(text)); | |
} | |
public static XmlElementAsDictionary Parse(Stream stream) | |
{ | |
if (stream == null) throw new ArgumentNullException("stream"); | |
return Parse(QuickIO.StreamToString(stream)); | |
} | |
public static IEnumerable<XmlElementAsDictionary> ParseDescendants(string text, string elementName) | |
{ | |
var element = XElement.Parse(text); | |
var xname = element.ResolveName(elementName); | |
return element.Descendants(xname) | |
.OrIfEmpty(element.Descendants(elementName)) | |
.Select(e => new XmlElementAsDictionary(e)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The main advantage with the above being that you can use namespace-qualified names, e.g.
xml["edm:Type"].Value;