Turp
Turp

Reputation: 708

LINQ Statement WHERE Question

I am returning a list. This is contains the names of xml nodes that cannot be blank in my XML file.

List<Setting> settingList = SettingsGateway.GetBySettingTypeList("VerifyField");

I have a LINQ Statement. I am trying to return all transactions that have empty nodes. The list here is returning the nodes that CANNOT be empty. Does anyone know what I am doing wrong here?

The following code is supposed to Bind the "transactions" to a DataGrid and display the Txn's that have empty nodes which are required.

var transactionList =
from transactions in root.Elements(XName.Get("Transactions")).Elements().AsEnumerable()
where transactions.Elements().Any
(
    el => 
    //String.IsNullOrEmpty(el.Value) &&
    //elementsThatCannotBeEmpty.Contains(el.Name)
    settingList.Any(
        name => String.IsNullOrEmpty(el.Element(name.SettingValue).Value)
    )
)
select new
{
    CustomerName = transactions.Element(XName.Get("CustomerName")).Value,
    ConfirmationNumber = transactions.Element(XName.Get("ConfirmationNumber")).Value
 };

 GridView.DataSource = transactionList;
 GridView.DataBind();

XML File Example:

<OnlineBanking>
  <Transactions>
    <Txn>
      <UserName>John Smith</UserName>
      <CustomerStreet>123 Main</CustomerStreet>
      <CustomerStreet2></CustomerStreet2>
      <CustomerCity>New York</CustomerCity>
      <CustomerState>NY</CustomerState>
      <CustomerZip>12345</CustomerZip>
    </Txn>
  </Transactions>
</OnlineBanking>

Upvotes: 0

Views: 159

Answers (2)

Tocco
Tocco

Reputation: 1705

Something like this:

var transactionList =
     root
    .Elements(XName.Get("Transactions")) //Get <Transaction> elements
    .Elements() //Get <Txn> elements
    .Where(txn => txn.Elements().Any(e => e.Value == String.Empty))  //Filter <Txn> Elements if it have any element like this: <CustomerStreet2></CustomerStreet2>
    .Select(x => new {
        PropertyX = x.Element(XName.Get("UserName")),
        PropertyY = x.Element(XName.Get("CustomerStreet")),
                    ...
    });

Works with:

<OnlineBanking>
  <Transactions>
    <Txn> <!-- This one matches! -->
      <UserName>John Smith</UserName>
      <CustomerStreet>123 Main</CustomerStreet>
      <CustomerStreet2></CustomerStreet2> 
      <CustomerCity>New York</CustomerCity>
      <CustomerState>NY</CustomerState>
      <CustomerZip>12345</CustomerZip>
    </Txn>
    <Txn> <!-- This one doesn't match! -->
      <UserName>John Smith</UserName>
      <CustomerStreet>123 Main</CustomerStreet>
      <CustomerStreet2>ASDASD</CustomerStreet2>
      <CustomerCity>New York</CustomerCity>
      <CustomerState>NY</CustomerState>
      <CustomerZip>12345</CustomerZip>
    </Txn>
  </Transactions>
</OnlineBanking>

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1503839

Okay, first problem: if the element is missing, you'll get a NullReferenceException.

I'd suggest creating a List<string> of the elements which can't be null, to make the query simple. Then:

var requiredElements = settingList.Select(x => x.SettingValue).ToList();

var transactionList = root
      .Elements("Transactions")
      .Elements("Txn")
      .Where(x => requiredElements
                    .Any(name => string.IsNullOrEmpty((string) x.Element(name)));

I think that should be okay, and slightly simpler than your original code... but to be honest, your original code looks like it should have worked anyway. What did it actually do? You haven't been very clear about the actual results versus the expected ones...

Upvotes: 3

Related Questions