1

My Goal: I want to parse a XML file for Catalog Number 987654 and display it in a textbox. My XML file looks like this:

<?xml version="1.0"?>
<!-- This file was generated by the installer. -->
<ModificationMap>
     <replace>
     <replace>
     <replace>
          <!-- Changed Serial Number and Product ID -->
          <text symbol="__EXAMPLE_SERIALNUMBER__">123456789</text>
          <text symbol="__EXAMPLE_CATALOGNUMBER__">987654</text>
          <text symbol="__MY_XMLPROGRAM__">300</text>
          <text symbol="__REGISTRATION_EXAMPLE__">20</text>
          <text symbol="__REGISTRATION_EXAMPLEVERSION__">20</text>
               <!-- Asset Profile -->
          <text symbol="__ASSET_MEMBERNAME__">MY_PROGRAM</text>
          <text symbol="__ASSET_FRIENDLYNAME__">XMLFile</text>
          <text symbol="__ASSET_DESCRIPTION__">XMLFile</text>
     </replace>
     <replace>
     <delete>
     <replace>
     <replace>
</ModificationMap>

Code:

    public Form1()
    {
        InitializeComponent();

        var dict = XDocument.Load(@"C:\Users\Smith\Desktop\example.xml")
        .Descendants("text")
        .ToDictionary(f => f.Attribute("__EXAMPLE_CATALOGNUMBER__").Value,
                      f => f.Attribute("symbol").Value);
        textBox1.Text = dict["__EXAMPLE_CATALOGNUMBER__"];
    }

I am getting an error telling me:

NullReferenceException was unhandled.

I think this approach to my goal is wrong. I am new to C# coding.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Smith
  • 387
  • 3
  • 6
  • 14

1 Answers1

2

The issue is this code:

f.Attribute("__REGISTRATION_CATALOGNUMBER__").Value

there is not attribute named __REGISTRATION_CATALOGNUMBER__. Now, you might want to do something more along these lines:

f.Attributes().Where(a => a.Value == "__REGISTRATION_CATALOGNUMBER__")
    .First().Value;

but even at that, I'm not sure what that would accomplish.

At any rate, f.Attribute("__REGISTRATION_CATALOGNUMBER__").Value is going to throw a NullReferenceException because Attribute(...) is going to return null.

It's quite likely what you're really looking for is this:

.ToDictionary(f => f.Attribute("symbol").Value,
              f => f.Value);

that would give you the symbol -> element value KVP.

Mike Perrenoud
  • 66,820
  • 29
  • 157
  • 232
  • @Smith, but it's likely that some of the other `symbol` values repeat. Either narrow down the search by adding a `Where` before the `ToDictionary`, or concatenate two values (you'll have to figure out which ones) to create a unique key. – Mike Perrenoud Sep 17 '13 at 19:34