0

I am running this line of code, which executes perfect for roughly 800 of my records. It hits record 801, and I am thrown

An unhandled exception of type 'System.NullReferenceException' occurred in XMLPost.exe

Additional information: Object reference not set to an instance of an object.

This is the troublesome line of code, which I thought adding in the ?.Value would account for null elements.

string sr12 = xml.Element("Parent").Element("Child1").Element("Child2").Element("Child3").Element("Child4").Element("Child5").Element("sr12")?.Value;
Console.WriteLine(sr12);

What should I alter for my variable sr12 so that it does not break and my code can continue to execute as expected?

EDIT

XML Structure

<parent>
<one>
    <two>
        <three>
            <sr12></sr12>
        </three>
    </two>
</one>
  <ten>
    <eleven>
        <twelve>
            <thirteen>
                <sr12></sr12>
            </thirteen>
        </twelve>
    </eleven>
  </ten>
</parent>

I have also tried this syntax

var result = (string) xml.Elements("Parent")
.Elements("ten")
.Elements("eleven")   
.Elements("twelve")
.Elements("thirteen")
.Elements("homeaddress")
.SingleOrDefault();

Which produces an error of

An unhandled exception of type 'System.InvalidOperationException' occurred in System.Core.dll
Additional information: Sequence contains more than one element

1 Answers1

0

If any of the elements in your query is missing, you will get this exception. The Element query either returns an XElement or it returns null.

You should use the Elements query. This returns all elements that match the name, and can be chained in the same way. The result of using this method would be that if any of the elements are missing, you simply get an empty sequence.

If you then call SingleOrDefault at the end, it will return either the single element returned by your query or null. You can then make use of the built in explicit conversion to string.

var result = (string) xml.Elements("Parent")
    .Elements("Child1")
    .Elements("Child2")   
    .Elements("Child3")
    .Elements("Child4")
    .Elements("Child5")
    .Elements("sr12")
    .SingleOrDefault();

Alternatively, if the absolute path is not that important (it may be that sr12 only appears at one point in the hierarchy), then you could use Descendants:

var result = (string) xml.Descendants("sr12").SingleOrDefault();
Charles Mager
  • 25,735
  • 2
  • 35
  • 45
  • I get this error - 'XElement' does not contain a definition for 'SingleOrDefault' and no extension method 'SingleOrDefault' accepting a first argument of type 'XElement' could be found – ToastedBread LeavesYouDead Jan 11 '17 at 15:04
  • @ToastedBreadLeavesYouDead sounds like you're still calling `Element` rather than `Elements`. Note the **s** at the end. – Charles Mager Jan 11 '17 at 15:05
  • good catch. I changed to Elements and now get an error of An unhandled exception of type 'System.InvalidOperationException' occurred in System.Core.dll Additional information: Sequence contains more than one element – ToastedBread LeavesYouDead Jan 11 '17 at 15:07
  • 2
    @ToastedBreadLeavesYouDead In which case there is more than one element called `sr12` returned by your query. You could use `FirstOrDefault` to get the first. It's hard to advise precisely without knowing what your XML looks like or what your specific use case is. – Charles Mager Jan 11 '17 at 15:08
  • See my edit - I think I am now providing the XML structure you need to see. – ToastedBread LeavesYouDead Jan 11 '17 at 15:14
  • And my specific use case is - I need to store the value in a variable so that I can Write To Console. – ToastedBread LeavesYouDead Jan 11 '17 at 15:54