Reputation: 2568
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
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
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