0

I'm working on some code to read and parse nodes of an XML file, and the layout of the file is kind complex (at least, it seems that way to me - having not done and XML parsing until this project).

The format for the xml files is similar to this:

<Parameters>
  <General>
    <Name>Name of this parameter</Name>
    <Caption>Information about the parameter</Caption>
    <GroupName>A Small Group of parameters</GroupName>
    <Value>1</Value>
    <Type>Boolean</Type>
    <Description>Some description</Description>
    <Dependencies>
      <And>
        <GroupName>Some other group of parameters</GroupName>
        <Name>The parameter this one is dependent on</Name>
      </And>
      <Or>
        <GroupName>Some other group of parameters</GroupName>
        <Name>The parameter this one might be dependent on</Name>
      </Or>
    </Dependencies>
  </General>
</Parameters>

I'm parsing the file in this manner:

XmlDocument xDoc = new XmlDocument();
Assembly _assembly = Assembly.GetExecutingAssembly();
Stream s = _assembly.GetManifestResourceStream(@"NameOfAssembly.NameOfFile.xml");
xDoc.Load(s);
xmlTests = xDoc.SelectNodes("/Parameters/General");
foreach (XmlNode rootType in xmlTests)
{
    switch (rootType.Name.ToString())
    {
        case "General":
            name = rootType["Name"].InnerText;
            caption = rootType["Caption"].InnerText;
            groupName = rootType["GroupName"].InnerText;
            mandatory = rootType["Mandatory"].InnerText;
            value = Convert.ToInt32(rootType["Value"].InnerText);
            typeOfData = rootType["Type"].InnerText;
            description = rootType["Description"].InnerText;
            //groupDepAnd = rootType["Dependencies/And/GroupName"].InnerText;
            //XmlNodeList dependenciesList = rootType.SelectNodes("Parameters/General/Dependencies/And");
            //foreach (XmlNode dependenciesAndNode in dependenciesList)
            //{
                //groupDepAnd = dependenciesAndNode["GroupName"].InnerText;
                //namesDepAnd = dependenciesAndNode["Names"].InnerText;
            //}
            //dependenciesList = rootType.SelectNodes("Parameters/General/Dependencies/Or");
            //foreach (XmlNode dependenciesOrNode in dependenciesList)
            //{
                //groupDepOr = dependenciesOrNode["GroupName"].InnerText;
                //namesDepOr = dependenciesOrNode["Names"].InnerText;
            //}
            /* send values to object constructor */
            break;
        default:
            break;
    }
}
/*close Stream, xDoc and such */

My problem arises when I'm parsing (or attempting to parse, as the case may be) the dependencies nodes. I'm not entirely sure on how to parse each of them (GroupName and Name from And, then GroupName and Name from Or) into a string. I've commented out the lines that don't seem to work how I want them to.

The foreach loops that I've commented out, obviously read through all mentions of Dependencies in the General Node List. And the line that starts "groupDepAnd = " (line 18) fails giving me a null reference exception.

Am I attempting to parse this XML file correctly? What am I doing wrong? Any and all help will be much appreciated. As I said earlier, my experience with XML is very limited.

Jamie Taylor
  • 1,644
  • 1
  • 18
  • 42

1 Answers1

1

The problems you're having are will probably be solved by these fixes:

//this selects the value of just the first 'And' node, SelectSingleNode lets you use XPath
groupDepAnd = rootType.SelectSingleNode("Dependencies/And/GroupName").InnerText;  

//You were using the wrong XPath to get the collection, rootType is already at /Parameters/General
XmlNodeList dependenciesList = rootType.SelectNodes("Dependencies/And");

Hope that helps, it's also worth noting that in the loop you will need to do something if there are multiple And or Or nodes, at the moment you're just overwriting the old values.

One other thing I'd add is that you can also use the newer XDocument instead of XmlDocument. Some people much prefer it as it's more Linq-esque. It's even John Skeet approved:

XDocument or XmlDocument

Community
  • 1
  • 1
mattmanser
  • 5,719
  • 3
  • 38
  • 50