2
\$\begingroup\$

After my question on StackOverflow, I've written code that should create a Config class from an XML file. XML loading is mixed with structures declaration and break in a lot of small pieces.

However, I'm not sure if this is bad or good. How would you refactor this? Probably some simple design pattern can be used, but again, I'm not sure that I should use design patterns for such simple things as XML loading.

using System;
using System.Net;
using System.Xml;

namespace Fast.Config
{
public class Config
{
    public Config(string configFile)
    {
        Load(configFile);
    }

    public Channel Fond { get; private set; }

    private void Load(string file)
    {
        XmlDocument doc = new XmlDocument();
        doc.Load(file);

        XmlElement fondChannel = doc.SelectNodes("//channel[@id=\"FOND\"]")[0] as XmlElement;
        Fond = new Channel(fondChannel);
     }
}

public class Channel
{
    public Channel(XmlElement channel)
    {
        Load(channel);
    }

    private void Load(XmlElement node)
    {
        var connections = node.SelectNodes(".//connections");
        var ordersIncrementalConnection = (connections[0] as XmlElement).SelectNodes(".//connection[@id=\"OLR\"]");
        OrdersIncremental = new Connection(ordersIncrementalConnection[0] as XmlElement);
    }

    public Connection OrdersIncremental { get; private set; }
}

public class Connection
{
    public Connection(XmlElement connection)
    {
        Load(connection);
    }

    private void Load(XmlElement connection)
    {
        XmlElement feedA =
            connection.SelectNodes(".//feed[@id=\"A\"]")[0] as XmlElement;
        FeedA = new Feed(feedA);

        XmlElement feedB =
            connection.SelectNodes(".//feed[@id=\"B\"]")[0] as XmlElement;
        FeedB = new Feed(feedB);
    }

    public Feed FeedA { get; private set; }
    public Feed FeedB { get; private set; }
}

public class Feed
{
    public Feed(XmlElement feed)
    {
        Load(feed);
    }

    private void Load(XmlElement feed)
    {
    }

}

}
\$\endgroup\$
4
\$\begingroup\$

If you choose to manually parse the Xml document for loading only, I would prefer not to use the XmlDocument classes. They have a performance penalty. Instead use the XPathDocument and the XPathNavigator class to navigate trough your document.

    void ReadXml(XmlReader reader)
    {
        XPathDocument document = new XPathDocument( reader );
        XPathNavigator navigator = document.CreateNavigator();

        foreach (XPathNavigator nav in navigator.Select( "/*/*" ))
        {
            string keyValue = nav.GetAttribute( "SomeAttribute", navigator.NamespaceURI );               
        }
    }

Second, i would prefer not to manually parse XML at all but create strong-typed classes in your project that you can serialize and deserialize. That makes the usage of you configuration more easy.

\$\endgroup\$
1
\$\begingroup\$

Make sure you code defensively, I see many potential null reference exceptions. Verify all inputs (what happens if you put a null value or a string like "adsf") in your Config constructor. What happens if you don't have a xml file in the proper configuration, what if a node is missing?

\$\endgroup\$
  • \$\begingroup\$ this code is not something i'm going to sell. this is for me and i always have well-formed xml file. however i need code that easy to support \$\endgroup\$ – javapowered Mar 18 '12 at 9:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.