Saturday, December 1, 2012

C# Reading XML Recursively (XmlDocument)

I'll be honest - I hate Recursion! But, nothing you can do, there are some situations when you know - this problem should be solved with Recursion. One of such problems is XML reading.
Today I'll show a simple example of reading XmlDocument recursively.

This is our XML:
<employees>
    <employee Id="1001" Name="John" Position="Developer">    
        <projects>
            <project Code="Rocket">                
                <budget>7000</budget>
            </project>
        </projects>
    </employee>

    <employee Id="1002" Name="Tomas" Position="Helpdesk">    
        <projects>
            <project Code="Orlando">                
                <budget>1000</budget>
            </project>
            <project Code="Newman">                
                <budget>900</budget>
            </project>
        </projects>
    </employee>
    
    <employee Id="1003" Name="Susan" Position="QA">        
        <projects>            
            <project Code="Newman">                
                <budget>900</budget>
            </project>
            <project Code="Rocket">                
                <budget>7000</budget>
            </project>
            <project Code="Orlando">                
                <budget>1000</budget>
            </project>
        </projects>
    </employee>  
</employees>
And, for example, I want to print the names of employees that participated in Orlando project. Of course, this task could be done with LINQ, but this time we want to see some recursion, right? :) Here is the code:
static void Main(string[] args)
{
    XmlDocument doc = new XmlDocument();
    doc.Load("../../Employees.xml");
    XmlNode root = doc.SelectSingleNode("*"); 
    ReadXML(root);
}

private static void ReadXML(XmlNode root)
{
    if (root is XmlElement)
    {
        DoWork(root);

        if (root.HasChildNodes)
            ReadXML(root.FirstChild);
        if (root.NextSibling != null)
            ReadXML(root.NextSibling);
    }
    else if (root is XmlText)
    {}
    else if (root is XmlComment)
    {}
}

private static void DoWork(XmlNode node)
{
    if (node.Attributes["Code"] != null)
        if(node.Name == "project" && node.Attributes["Code"].Value == "Orlando")
            Console.WriteLine(node.ParentNode.ParentNode.Attributes["Name"].Value);
}
Reading XML recursively in C# - result

So, I go over each XmlNode by calling XMLRead method. Of course, we need some logic, which is in DoWork method. Inside the XMLRead method I specified that I'm interesting only in XmlElement. As you can see from the source code, you can specify not only XmlElement, but also XmlComment or other XmlNode type, if you need. All this stuff looks very simple until you starting to remove XML elements. Don't forget that once you removed an XML node, the whole XML structure is changed.

Download the source code (Visual Studio 2012 project).

1 comment: