views:

283

answers:

3

I'm having trouble getting my program to read this XML file properly, it will need to write to it also but not yet. Just note that this is only a little bit of the code

XmlDocument InstalledList = new XmlDocument();
InstalledList.Load(AppsInstalledFileNamePath);

//Sets the PackageNode to the correct part of the XmlDocument
XmlNodeList PackagesNode = InstalledList.GetElementsByTagName("installed");

foreach (XmlNode InstalledListNodes in PackagesNode)
{
    //If the title is the same as what the user typed, continue on
    if (InstalledListNodes.Attributes["title"].InnerText.Equals(packagename) == true)
    {
        BatchProcessFileName = InstalledListNodes.Attributes["uninstallername"].InnerText;
        Console.WriteLine("Filename OK");

I also took the try statement out so I wouldn't have to add the catch

Below is the XML File that it is trying to read (and later write)

<?xml version="1.0" encoding="utf-8" ?>
<packages>
  <installed>
  <sampleapp title="sampleapp" id="00001" uninstallername="sampleapp.bat" installdate="11/15/09"></sampleapp>
  <sampleapp2 title="sampleapp2" id="00002" uninstallername="sampleapp2.bat" installdate="11/16/09"></sampleapp2>
  </installed>
  <uninstalled>

 </uninstalled>
</packages>

The code runs, but it has a NullReference Exception at

InstalledListNodes.Attributes["title"].InnerText.Equals(packagename) == true
+1  A: 

Well, I can see three different failure points in the following line:

InstalledListNodes.Attributes["title"].InnerText.Equals(packagename) == true
   ^--Null?                 ^-- Null?    ^--Null?

I would break that long chain up into more discrete elements, and check for null on each one to narrow it down:

   if (InstalledListNodes != null)
   {
       var attribute = InstalledListNodes.Attributes["title"]; 
       if (attribute != null)
       {
           if (attribute.InnerText.Equals(packagename) == true)
           {
              // ...
           }
       }
   }

That said, I would use the .Value property rather than the .InnerText property when retrieving attribute values. InnerText should be used when retrieving text content from within element open and close tags.

jrista
+1 Totally agree with the null-tests, but... neither `Value` nor `InnerText` will ever be null for an attribute.
Abel
@Abel: You are correct. I've updated the example to reflect.
jrista
+1  A: 

Seems a small typo;

Note you wrote Attributes["unintallername"] and it should be Attributes["uninstallername"]

Rubens Farias
+1  A: 
Abel
Thanks a shitload man, that last end with XPath fixed it!
Indebi
You're welcome! PS: you can also use XPath to select your packagenames in one go, removing the need to loop manually: `SelectNodes(String.Format("packages/installed/*[title='{0}']", packagename))`. Saves a lot of trouble!
Abel
Thanks for the downvote, but care to elaborate on why? I'd gladly update my answer to correct any mistakes.
Abel
I accidently hit the Up again lol sorry, and it wont let me hit up one more time
Indebi