Exclude null object reference exception when accessing subitems that may or may not exist

I have: XML with some elements. A subitem that may or may not be defined inside this XML. You must extract the value of the subitem when it exists.

How to get value without metadata about object errors?

For instance:

 string sampleXML = "<Root><Tag1>tag1value</Tag1></Root>"; 

//Pass in <Tag2> and the code works: 
//string sampleXML = "<Root><Tag1>tag1value</Tag1><Tag2>tag2Value</Tag2></Root>";    
 XDocument sampleDoc = XDocument.Parse(sampleXML);

//Below code is in another method, the 'sampleDoc' is passed in. I am hoping to change only this code
XElement sampleEl = sampleDoc.Root; 
string tag1 = String.IsNullOrEmpty(sampleEl.Element("Tag1").Value) ? "" : sampleEl.Element("Tag1").Value;

//NullReferenceException:
//Object reference not set to an instance of an object.
string tag2 = String.IsNullOrEmpty(sampleEl.Element("Tag2").Value) ? "" : sampleEl.Element("Tag2").Value;
+3
source share
8 answers

First you need to check if the document is null, remember that you are accessing .Value, and this will eliminate the null reference, so before applying .value, do a test:

if (sampleEl != null)
  //now apply .value

Or triple:

string tag2 = sampleEl.Element("Tag2") != null ? sampleEL.Element("Tag2").Value : String.Empty

Then your code will look like this:

 string sampleXML = "<Root><Tag1>tag1value</Tag1></Root>"; 

    //Pass in <Tag2> and the code works: 
    //string sampleXML = "<Root><Tag1>tag1value</Tag1><Tag2>tag2Value</Tag2></Root>";    
     XDocument sampleDoc = XDocument.Parse(sampleXML);

    //Below code is in another method, the 'sampleDoc' is passed in. I am hoping to change only this code
    XElement sampleEl = sampleDoc.Root; 
    string tag1 = sampleEl.Element("Tag1") != null ? sampleEl.Element("Tag1").Value : String.Empty;

    //NullReferenceException:
    //Object reference not set to an instance of an object.
string tag2 = sampleEl.Element("Tag2") != null ? sampleEL.Element("Tag2").Value : String.Empty
+2
source

null-coalescing-operator :

 string tag1= (string)sampleEl.Element("Tag1") ?? string.Empty;

, LINQ to XML ( - ), null, .

+10

null, . , , .

public static string GetElementValue(this XElement parent, string elementName) {
  if (parent == null) { 
    return string.Empty;
  }
  var element = parent.Element(elementName);
  if (element == null || element.Value == null) {
    return string.Empty;
  }
  return element.Value;
}

string tag1 = sampleEl.GetElementValue("Tag1");
string tag2 = sampleEl.GetElementValue("Tag2");
+3

# :

string tag2 = sampleEl.Element("Tag2") == null ? "" : sampleEl.Element("Tag2").Value;
+3
string tag1 = sampleEl.Element("Tag1") != null ? sampleEl.Element("Tag1").Value : string.Empty;
+1

. , - null:

public static TOut ValueOrDefault<TIn, TOut>(this TIn input, Func<TIn, TOut> projection, TOut defaultValue)
        where TOut : class
    {
        try
        {
            return projection(input) ?? defaultValue;
        }
        catch (NullReferenceException)
        {
            return defaultValue;
        }
        catch (InvalidOperationException)
        {
            return defaultValue;
        }
    }

:

var value = topObject.ValueOrDefault(x=>x.ChildObject.AnotherChild.ChildProperty, String.Empty);

value , topObject, ChildObject, AnotherChild ChildProperty null. , , ChildProperty ( ). NullReferenceException . InvalidOperationException Value NULL.

+1

# 6.0 :

 string uniqueIdentifier = myNode.Document?.Element("elem1")?.Element("elem2")?.Attribute("attribute1")?.Value;
+1

Just for fun, here is a solution using LINQ to XML that

  • requires only one operator and
  • you don’t need a ternary operator, so you don’t need to specify a tag name twice:

    string tag1 = sampleEl.Elements("Tag1").Select(x => x.Value).FirstOrDefault();
    string tag2 = sampleEl.Elements("Tag2").Select(x => x.Value).FirstOrDefault();
    

Add ?? ""if you need an empty string instead nullif the tag does not exist.

0
source

All Articles