punkouter
punkouter

Reputation: 5366

Projecting object with LINQ to XML but want empty string instead of NULL

Sometimes the XML will be missing certain parts. In this case the XML sometimes does not have a 'Email'. So in that case I just want an empty string. Here is what I have attempted so far but I still get an

Additional information: Value cannot be null.

Here is the code and a piece of XML

XDocument xdoc = XDocument.Parse(result.Result.ToString());

SelectedLead = xdoc.Descendants("Fields").Select(x => new Lead
{
    FirstName = x.Descendants("Field").Where(y => y.Attribute("FieldTitle").Value == "First Name").Select(z => z.Attribute("Value").Value).FirstOrDefault(),
    LastName = x.Descendants("Field").Where(y => y.Attribute("FieldTitle").Value == "Last Name").Select(z => z.Attribute("Value").Value).FirstOrDefault(),
    Email = x.Descendants("Field").Where(y => y.AttributeValueNull("FieldTitle") == "Email").Select(z => z.Attribute("Value").Value).FirstOrDefault()
}).First();

public static string AttributeValueNull(this XElement element, string attributeName)
{
    if (element == null)
        return "";
    else
    {
        XAttribute attr = element.Attribute(attributeName);
        return attr == null ? "" : attr.Value;
    }
}

XML:

<Fields>
<Field FieldId="2" Value="John" FieldTitle="First Name" FieldType="Text" />
<Field FieldId="3" Value="Smith" FieldTitle="Last Name" FieldType="Text" />
<Field FieldId="9" Value="123 abc st" FieldTitle="Address" FieldType="Text" />
<Field FieldId="10" Value="Cincinnati" FieldTitle="City" FieldType="Text" />
<Field FieldId="11" Value="OH" FieldTitle="State" FieldType="State" />
</Fields>

Upvotes: 0

Views: 196

Answers (2)

Charles Mager
Charles Mager

Reputation: 26223

Most of your AttributeValueNull can be removed by making use of the defined explicit conversions, e.g:

return (string)element.Attribute(attributeName);

Then it may be less repetitive to incorporate this into a helper method to get your field values:

private static string FieldValue(XElement fields, string fieldTitle)
{
    return fields.Elements("Field")
        .Where(e => (string)e.Attribute("FieldTitle") == fieldTitle)
        .Select(e => (string)e.Attribute("Value"))
        .SingleOrDefault() ?? string.Empty;
}

And putting this together:

var lead = doc.Descendants("Fields").Select(fields => new Lead
    {
        FirstName = FieldValue(fields, "First Name"),
        LastName = FieldValue(fields, "Last Name"),
        Email = FieldValue(fields, "Email")
    }).Single();  

You can see a working demo here: https://dotnetfiddle.net/TQJsv4

Upvotes: 1

punkouter
punkouter

Reputation: 5366

The answer is this

  Email = x.Descendants("Field").Where(y => y.AttributeValueNull("FieldTitle") == "Email")
           .Select(z => z.Attribute("Value").Value).FirstOrDefault() ?? string.Empty

Upvotes: 0

Related Questions