Hacking the BaseURI onto a ConfigXmlDocument

Ok, so if you read this previous post, you’d know that I ran into a problem with ConfigXmlDocument not setting the BaseURI property making resolution of relative URIs within the document completely unpredictable and utterly useless. I really wanted it to work and knew there had to be a way, so I fgured out the following workaround (aka hack).

public sealed class HackedConfigurationNodeReader : XmlNodeReader
{
    #region Fields

    private string configurationFilePath;

    #endregion

    #region Constructors

    public HackedConfigurationNodeReader(string configurationFilePath, XmlNode configurationNode) : base(configurationNode)
    {
        this.configurationFilePath = configurationFilePath;
    }

    #endregion

    #region Base class overrides

    public override string BaseURI
    {
        get
        {
            return this.configurationFilePath
        }
    }

    #endregion
}

Now, all you need to do inside your IConfigurationSectionHandler::Create override is the following:

public object Create(object parent, object configContext, XmlNode sectionNode)
{
    // HACK: If configuration XML document's BaseURI is not set, use our hacked reader
    if(sectionNode.BaseURI.Length == 0)
    {
        reader = new HackedConfigurationNodeReader(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile, sectionNode);
    }
    else
    {
        reader = new XmlNodeReader(sectionNode);
    }

    // Now pass the reader on to some class that expects a BaseURI for resolving relative URIs
    SomeXmlReadingObject object = new SomeXmlReadingObject();
    object.ReadXml(reader);
 }

The key here was that I want my SomeXmlReadingObject instance to be able to parse XML with relative URIs from a configuration section the same as it would parse XML from any other mechanism that passed it an XmlReader.

Leave a Reply