Merging collections
JK | Thu, 2008/12/04 - 14:44
ICollection does not offer a method for merging two collections. As merging collections was exactly what I needed, I wrote a bit of code for it. An extension method seemed to offer the most elegant solution:
public static ICollection<T> Add<T>(this IList<T> self, IList<T> input)
{
foreach (T item in input)
{
self.Add(item);
}
return self;
}
Because I've overloaded the Add method, this will now work:
IList<string> list1 = new IList<string>(); IList<string> list2 = new IList<string>(); string name = 'J2'; list1.Add(list2); list1.Add(name);
For the license to this code, see http://creativecommons.org/licenses/by/3.0/
XmlDocument improved
JK | Fri, 2008/08/29 - 22:10
On a nice summerday I set out to write a command line tool that would change values in xml documents. You would pass it a document name, an xpath query, and a value, and it would update the element found in the document through the query, and set its content to the new value.
So I created this tool, and all was fine. That is, until I encountered a document that contained namespaces. I created a namespace manager, figured out how to dynamically get the namespace information from the xml document, and now I could use the namespaces in the xpath expression.
Not an impressive feat, but it left me wondering why System.Xml.XmlDocument doesn't do the "heavy" lifting for us. I decided it should, and you'll find my fix after the break.
using System;
namespace J2.Xml
{
/* created by http://j2solutions.nl - 20080824
* XmlDocument that automatically loads all namespaces.
* The default namespace, if present, gets the prefix 'default'.
* license: http://creativecommons.org/licenses/by/3.0/
*/
public class XmlDocument : System.Xml.XmlDocument
{
private const string DEFAULT_DEFAULT_NS_PREFIX = "default";
System.Xml.XmlNamespaceManager nsmgr = null;
public string DefaultNsPrefix { get; set; }
public XmlDocument()
{
DefaultNsPrefix = DEFAULT_DEFAULT_NS_PREFIX;
}
#region Load
public new void Load(string filename)
{
base.Load(filename);
nsmgr = CreateNamespaceMgr(DefaultNsPrefix);
}
public new void Load(System.IO.Stream inStream)
{
base.Load(inStream);
nsmgr = CreateNamespaceMgr(DefaultNsPrefix);
}
public new void Load(System.IO.TextReader txtReader)
{
base.Load(txtReader);
nsmgr = CreateNamespaceMgr(DefaultNsPrefix);
}
public new void Load(System.Xml.XmlReader reader)
{
base.Load(reader);
nsmgr = CreateNamespaceMgr(DefaultNsPrefix);
}
#endregion
#region LoadXml
public new void LoadXml(string xml)
{
base.LoadXml(xml);
nsmgr = CreateNamespaceMgr(DefaultNsPrefix);
}
#endregion
#region SelectSingleNode
public new System.Xml.XmlNode SelectSingleNode(string xpath)
{
return (null != nsmgr) ? base.SelectSingleNode(xpath, nsmgr) : base.SelectSingleNode(xpath);
}
private new System.Xml.XmlNode SelectSingleNode(string xpath, System.Xml.XmlNamespaceManager nsmgr)
{
throw new NotSupportedException();
}
#endregion
#region SelectNodes
public new System.Xml.XmlNodeList SelectNodes(string xpath)
{
return (null != nsmgr) ? base.SelectNodes(xpath, nsmgr) : base.SelectNodes(xpath);
}
private new System.Xml.XmlNodeList SelectNodes(string xpath, System.Xml.XmlNamespaceManager nsmgr)
{
throw new NotSupportedException();
}
#endregion
private System.Xml.XmlNamespaceManager CreateNamespaceMgr(string prefixForDefaultNS)
{
System.Collections.Specialized.NameValueCollection namespaces = GetNamespaces(base.DocumentElement, prefixForDefaultNS);
System.Xml.XmlNamespaceManager namespaceMgr = null;
if (0 != namespaces.Count)
{
namespaceMgr = new System.Xml.XmlNamespaceManager(base.NameTable);
for (int i = 0; i < namespaces.Count; i++)
{
namespaceMgr.AddNamespace(namespaces.Keys[i], namespaces[i]);
}
}
return namespaceMgr;
}
private System.Collections.Specialized.NameValueCollection GetNamespaces(System.Xml.XmlElement doc, string prefixForDefaultNS)
{
System.Collections.Specialized.NameValueCollection ret = new System.Collections.Specialized.NameValueCollection();
foreach (System.Xml.XmlAttribute attr in doc.Attributes)
{
if (-1 < attr.Name.IndexOf("xmlns"))
{
// xmlns=<uri> is the default namespace, xmlns:<name>=<uri> is a named namespace
string key = (-1 < attr.Name.IndexOf("xmlns:")) ? attr.Name.Replace("xmlns:", "") : prefixForDefaultNS;
ret.Add(key, attr.Value);
}
}
return ret;
}
}
}
For the license to this code, see http://creativecommons.org/licenses/by/3.0/
