简体   繁体   中英

Iterating Between Two XML Node Selected Values Using C#

This is my XML file called "Buying Bills.xml" where BILLS is the root:

    <?xml version="1.0" encoding="utf-8"?>
<BILLS>
  <BILL>
    <DATE>24/11/2013 10:55:08 ص</DATE>
    <LIST>
      <NAME>Corded Cyclonic Stick Vacuum</NAME>
      <NUMBER>2</NUMBER>
      <PRICE>159.98</PRICE>
      <NAME>Table Fan</NAME>
      <NUMBER>3</NUMBER>
      <PRICE>239.97</PRICE>
      <NAME>Kenmore Elite  31.0 cu. ft. French Door Bottom-Freezer Refrigerator</NAME>
      <NUMBER>1</NUMBER>
      <PRICE>1999.99</PRICE>
      <NAME>Electric Freestanding Range 700 Series</NAME>
      <NUMBER>1</NUMBER>
      <PRICE>1999.00</PRICE>
      <NAME>Rocky 2 Washer</NAME>
      <NUMBER>2</NUMBER>
      <PRICE>1970.00</PRICE>
    </LIST>
  </BILL>
  <BILL>
    <DATE>21/11/2013 02:09:15 ص</DATE>
    <LIST>
      <NAME>Air Steerable Bagless Upright</NAME>
      <NUMBER>3</NUMBER>
      <PRICE>569.97</PRICE>
      <NAME>Table Fan</NAME>
      <NUMBER>5</NUMBER>
      <PRICE>399.95</PRICE>
      <NAME>Kenmore  25.4 cu. ft. Side-by-Side Refrigerator</NAME>
      <NUMBER>3</NUMBER>
      <PRICE>2399.97</PRICE>
      <NAME>Electric Freestanding Range 700 Series</NAME>
      <NUMBER>2</NUMBER>
      <PRICE>3998.00</PRICE>
      <NAME>Rocky 2 Washer</NAME>
      <NUMBER>4</NUMBER>
      <PRICE>3940.00</PRICE>
    </LIST>
  </BILL>
  <BILL>
    <DATE>21/11/2013 02:03:25 ص</DATE>
    <LIST>
      <NAME>Corded Cyclonic Stick Vacuum</NAME>
      <NUMBER>3</NUMBER>
      <PRICE>239.97</PRICE>
    </LIST>
  </BILL>
  <BILL>
    <DATE>21/11/2013 01:57:55 ص</DATE>
    <LIST>
      <NAME>Quietforce Bagged Canister</NAME>
      <NUMBER>2</NUMBER>
      <PRICE>299.99</PRICE>
      <NAME>Table Fan</NAME>
      <NUMBER>5</NUMBER>
      <PRICE>79.99</PRICE>
      <NAME>Kenmore  18.2 cu. ft. Top-Freezer Refrigerator</NAME>
      <NUMBER>4</NUMBER>
      <PRICE>499.99</PRICE>
      <NAME>Electric Slide-in Range 700 Series</NAME>
      <NUMBER>7</NUMBER>
      <PRICE>2,499.00</PRICE>
      <NAME>Rocky 2 Washer</NAME>
      <NUMBER>6</NUMBER>
      <PRICE>985.00</PRICE>
    </LIST>
  </BILL>
</BILLS>

I have on my form two comboBoxes each contain all dates from my XML file (2 identical lists). Let's say in comboBox1 I chosed the first date in the file and in comboBox2 I chosed the last date (or maybe the third...whatever), how can I obtain the sum of all prices from in between those two dates (not only the sum of the two selected dates prices but also the sum of the prices in between as well)....it's like sweeping all prices from from node X that contains first date and all the way to node Z that contains the second date and calculating the sum. And as the title says using C#. Thanks in advance guys :)

You can use Linq to Xml:

var xdoc = XDocument.Load(fileName);
var bills = from b in xdoc.Descendants("BILL")
            group b by (string)b.Element("DATE") into g
            select new {
                Date = g.Key,
                TotalPrice = g.Element("LIST")                              
                              .Elements("PRICE")
                              .Sum(p => (decimal)p)
            };

Now you can bind bills to combobox. Use Date as display member, and TotalPrice as value member. Or you just can search for total price of selected date:

var price = bills.First(b => b.Date == date).TotalPrice;

UPDATE: Following query returns total price of several dates:

string[] dates = // get selected dates
var price = bills.Where(b => dates.Contains(b.Date))
                 .Sum(b => b.TotalPrice);

By what your question seems to be asking is selecting one of the dates in the combobox you want to sum the prices of the respective List which contains objects i guess of type like Product or something similar,for example,in your xml there are 2 Bill objects if you selected the date(in the combobox) of the second Bill object that only has 1 object in the list(therefore only 1 price),you would like to get that price,if this is what you need then you can achieve it with databinding,a crude example follows:

UPDATED: 1)declare a bindingsource in your form for example:

private BindingSource source = new BindingSource();
private BindingSource SecondSource = new BindingSource();

2)then in your form load place this code(renaming the combobox and the name of your xml file):

var serializer = new XmlSerializer(typeof(List<Bill>));

using(var reader = new StreamReader("YourFileNameHere.xml"))
{
     try
     {
        source.DataSource = (List<Bill>)serializer.Deserialize(reader);
     }
     catch (Exception ex)
     {
        MessageBox.Show(ex.Message);
     }
}

SecondSource.DataSource = source;
comboBox1.SelectedIndexChanged += new EventHandler(comboBox_SelectedIndexChanged);
comboBox2.SelectedIndexChanged += new EventHandler(comboBox_SelectedIndexChanged);

comboBox1.DisplayMember = "Date";
comboBox2.DisplayMember = "Date";
comboBox1.DataSource = source;
comboBox2.DataSource = SecondSource;

3)next the event-handler for the selected index changed:

void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
     var query = from combo in this.Controls.OfType<ComboBox>().Where(c => c.SelectedItem != null)
                 select ((Bill)combo.SelectedItem).Products.Sum(p => p.Price);
     textBox1.Text = query.Aggregate((d, a) => d + a).ToString();
}

4)one more thing,by your xml it would be better to formatt it better by adding attributes to your Bill class.Assuming your Bill class only has 2 members the date and the list,this next would produce more structured xml:

[Serializable]
[XmlRootAttribute(IsNullable = false, ElementName = "Bills",Namespace ="")]
public class Bill
{
    [XmlElement("Date")]
    public DateTime Date {get;set;}

    [XmlArray(ElementName = "Products")]
    public List<Product> Products { get; set; }
}

And that it everytime you select a diferent date in the combobox you will get the sum of all prices related to that Bill instance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM