How to collect namespaces used in a XML document

| 2 Comments | No TrackBacks

The question raised in the microsoft.public.dotnet.xml newsgroup today: "How to retrieve the namespace collection of all the document namespaces for which there is at least one element in the document". The purpose is a validation against different schemas. Well, the most effective way of doing it is during XML document reading phase, not after that. In .NET it means to add a slim layer into XML reading stack (aka SAX filter in Java world). In this layer, which is just custom class extending XmlTextReader, one can have a handler for an element start tag, whose only duty is to collect element's namepace and delegate the real work for the base XmlTextReader. Here is how easy it can be implemented.

public class NamespaceCollectingXmlReader : XmlTextReader 
{
    private Hashtable namespaces = new Hashtable();

    //Add constructors as needed
    public NamespaceCollectingXmlReader(string url) : base(url) {}

    public Hashtable CollectedNamespaces 
    {
        get { return namespaces; }
    }

    public override bool Read()
    {
        bool baseRead = base.Read();
        if (base.NodeType == XmlNodeType.Element && 
              base.NamespaceURI != "" &&
              !namespaces.ContainsKey(base.NamespaceURI))
            namespaces.Add(base.NamespaceURI, "");
        return baseRead;
    }
}
And here is how it can be used to collect namespaces while loading XML into a XmlDocument.
XmlDocument doc = new XmlDocument();
NamespaceCollectingXmlReader ncr = new NamespaceCollectingXmlReader("foo.xml");
doc.Load(ncr);
foreach (object ns in ncr.CollectedNamespaces.Keys)       
  Console.WriteLine(ns);

Related Blog Posts

No TrackBacks

TrackBack URL: http://www.tkachenko.com/cgi-bin/mt-tb.cgi/320

2 Comments

Yep, I was monitoring this one... :(

Slim layers such as these are the reason why I asked to have the v2 internal System.Xml.XmlWrappingReader public. I didn't succeed though :( (http://lab.msdn.microsoft.com/ProductFeedback/viewfeedback.aspx?feedbackid=ecdc5e48-7c3f-4ac1-b884-11e7d38daf17)

Leave a comment