ib11
ib11

Reputation: 2568

C# linq xml missing element gives throws exception

What I am trying to get is a list or array of values for each of an element.

But if the child element is missing, I would like to get an empty string.

This is what I have as a code, but when the child x is missing it does not return "" but throws an IllegalOperation exception:

var firstphs = xliff.Descendants()
                    .Elements(xmlns + "trans-unit")
                    .Elements(xmlns + "seg-source")
                    .Elements(xmlns+ "mrk")
                    .Where(e => e.Attribute("mtype").Value == "seg")
                    .Select(e => e.Elements(xmlns+"x").FirstOrDefault().Attribute("id").Value ?? "")
                    .ToArray();

Can somebody point out what is wrong in the code and how to correct it? Thanks.

Upvotes: 2

Views: 543

Answers (2)

har07
har07

Reputation: 89285

Accessing attribute in case FirstOrDefault() returns null would cause exception. You can try this way instead :

var firstphs = xliff.Descendants()
                    .Elements(xmlns + "trans-unit")
                    .Elements(xmlns + "seg-source")
                    .Elements(xmlns+ "mrk")
                    .Where(e => e.Attribute("mtype").Value == "seg")
                    .Select(e => e.Elements(xmlns+"x").Select(x => (string)x.Attribute("id")).FirstOrDefault())
                    .ToArray();

General useful tip : avoid using Value property in case an element or attribute may not exists. Instead, cast the element or attribute to string, as demonstrated in the above snippet.

Upvotes: 2

Philippe Leybaert
Philippe Leybaert

Reputation: 171774

If you are using C#6, you can do this:

var firstphs = xliff.Descendants()
                    .Elements(xmlns + "trans-unit")
                    .Elements(xmlns + "seg-source")
                    .Elements(xmlns+ "mrk")
                    .Where(e => e.Attribute("mtype").Value == "seg")
                    .Select(e => e.Elements(xmlns+"x").FirstOrDefault()?.Attribute("id").Value ?? "")
                    .ToArray();

Note the ?. after FirstOrDefault(). It's called the "null propagation operator" and it will return null whenever the expression to the left is null. If not, it will continue evaluating the expression.

Upvotes: 0

Related Questions