I have xml document:

<File> 
  <Record type="16">
    <Fields>
        <Field title="SummCode">470</Field>
        <Field title="Amount">100819</Field>
           etc...
    </Fields>
  </Record>
</File>

I have written the following statements to sum the values of the fields with the "Amount" attribute for all Fields elements where the value for the Field with the "SummCode" attribute is "470".

It works but I think I am overcomplicating it. I'm selecting down to the Field level and looking back up to Ancestors to get back to Field level. I'm curious if there is a better way.

var xml = XElement.Load(@"C:\XML File Generated 5-13-14.xml");
var sum = xml.Descendants("Field")
    .Where(r => r.Attribute("title").Value == "SummCode" && r.Value == "470")
    .Ancestors("Fields")
    .Elements("Field")
    .Where( s => s.Attribute("title").Value == "Amount")
    .Select (t => double.Parse(t.Value))
    .Sum();
有帮助吗?

解决方案

This works for me:

var sum = xml.Descendants("Fields")
    .Where(x => x.Elements("Field")
        .Any(r => r.Attribute("title").Value == "SummCode" && r.Value == "470"))
    .Elements("Field")
    .Where(x => x.Attribute("title").Value == "Amount")
    .Sum(x => (double)x);

I don't know if it is a great deal simpler though.

It does, however, correct a potential error in your query. If you had this xml:

<File> 
  <Record type="16">
     <Fields>
        <Field title="SummCode">470</Field>
        <Field title="SummCode">470</Field>
        <Field title="Amount">1</Field>
    </Fields>
  </Record>
</File>

Then your code returns 2, whereas mine would return 1. I don't know if that is possible with your file format or not though, or if it is your intent to return 2 in this case.


I thought I'd drop another alternative. This might be a bit stranger, but it also might be a bit easier to read.

var sum =
(
    from x in xml.Descendants("Fields")
    let fields = x.Elements("Field")
        .ToLookup(y => y.Attribute("title").Value, y => y.Value)
    where fields["SummCode"].Where(y => y == "470").Any()
    from a in fields["Amount"]
    select double.Parse(a)
).Sum();
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top