Skip to content

Instantly share code, notes, and snippets.

@markrendle
Created September 6, 2012 08:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save markrendle/3653184 to your computer and use it in GitHub Desktop.
Save markrendle/3653184 to your computer and use it in GitHub Desktop.
Utility classes for dealing with XML as Dictionaries
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;
}
}
}
}
}
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));
}
}
}
@markrendle
Copy link
Author

The main advantage with the above being that you can use namespace-qualified names, e.g. xml["edm:Type"].Value;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment