简体   繁体   中英

How can I sum population of all city in every utility(XML data) using c#?

I'm having following xml file

<?xml version="1.0" encoding="UTF-8"?>
<DetailedUtilityCollection SchemaVersion="1.0">
<DetailedUtility UtilityId="720" UtilityName="Chelan County Public Utility District" CountryCode="US" StateCode="WA">
  <Rate Id="2350" Name="Residential Service (Schedule 1)" Sector="Residential" Metering="OptionalNetMetering" IsDefault="true" IsTimeOfUse="false" />
  <Rate Id="2351" Name="General Service - Nondemand (Schedule 2)" Sector="Commercial" Metering="OptionalNetMetering" IsDefault="true" IsTimeOfUse="false" />
  <Rate Id="2352" Name="General Service - Demand (Schedule 2)" Sector="Commercial" Metering="OptionalNetMetering" IsDefault="false" IsTimeOfUse="false" />
  <City Name="Cashmere" Population="7233">
     <CityLocation Zip="98815" Lat="47.53593" Lng="-120.494571" />
  </City>
  <City Name="Chelan" Population="6394">
     <CityLocation Zip="98816" Lat="47.901204" Lng="-120.139618" />
  </City>
  <City Name="Entiat" Population="1953">
     <CityLocation Zip="98822" Lat="47.885389" Lng="-120.47078" />
  </City>
  <City Name="Leavenworth" Population="6504">
     <CityLocation Zip="98826" Lat="47.82259" Lng="-120.825267" />
  </City>
  <City Name="Wenatchee" Population="40977">
     <CityLocation Zip="98801" Lat="47.451974" Lng="-120.330783" />
     <CityLocation Zip="98802" Lat="47.494001" Lng="-120.193856" />
     <CityLocation Zip="98807" Lat="47.4236" Lng="-120.3092" />
  </City>
  <City Name="West Wenatchee" Population="40977">
     <CityLocation Zip="98801" Lat="47.451974" Lng="-120.330783" />
  </City>
  </DetailedUtility>
  <DetailedUtility UtilityId="721" UtilityName="Clallam County PUD" CountryCode="US" StateCode="WA">
  <Rate Id="2353" Name="General Service - Residential, Farm (Schedule E-4)" Sector="Residential" Metering="OptionalNetMetering" IsDefault="true" IsTimeOfUse="false" />
  <Rate Id="2354" Name="General Service - Commercial (Schedule E-4)" Sector="Commercial" Metering="OptionalNetMetering" IsDefault="true" IsTimeOfUse="false" />
  <Rate Id="2355" Name="Large Power Service (Schedule E-5)" Sector="Commercial" Metering="OptionalNetMetering" IsDefault="false" IsTimeOfUse="false" />
  <City Name="Forks" Population="6261">
     <CityLocation Zip="98331" Lat="47.851473" Lng="-124.28411" />
  </City>
  <City Name="Neah Bay" Population="1414">
     <CityLocation Zip="98357" Lat="48.332856" Lng="-124.639563" />
  </City>
  <City Name="Port Angeles" Population="22230">
     <CityLocation Zip="98362" Lat="47.99614" Lng="-123.38281" />
     <CityLocation Zip="98363" Lat="48.017263" Lng="-123.824588" />
  </City>
  <City Name="Port Angeles East" Population="-1" />
  <City Name="Sequim" Population="26856">
     <CityLocation Zip="98382" Lat="48.025762" Lng="-123.061784" />
  </City>
  </DetailedUtility>
  </DetailedUtilityCollection>

How can I get sum of all city population in every utilityid in c#. Please help me.

I've tried following codes but none is working for me.

xmlDoc.LoadXml(strFetchResData);

                        //dynamic BillUtilityData = JsonConvert.SerializeXmlNode(xmlDoc).Replace(@"@", @"").Remove(1, 44);
                        //dynamic BillUtilityData  = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeXmlNode(xmlDoc).Replace(@"@", @"").Remove(1, 44));
                        //dynamic BillUtilityData = JsonString;
                        XmlNodeList utilitylist = xmlDoc.DocumentElement.ChildNodes;

                        if (utilitylist.Count > 0)
                        {
                            foreach (XmlNode nodeUtil in utilitylist)
                            {
                                double? totalPopulation = 0;
                                //xmlDoc.Load(nodeUtil.InnerXml.ToString());
                                dynamic BillUtilityData = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeXmlNode(nodeUtil).Replace(@"@", @"").Remove(1, 44));
                                //totalPopulation = Convert.ToDouble((nodeUtil).LastChild.Attributes["Population"].Value);
                                //xmlDoc.LoadXml(nodeUtil.InnerText);


                                //foreach (XmlNode cityUtil in nodeUtil["City"])
                                //{
                                //    totalPopulation = SunpowerServiceMethods.calculateTotalPopulationOfCitySiblings(cityUtil,totalPopulation);
                                //    break;
                                //}

                            }

EDIT: Thus your real XML file has namespaces declared, you should deal with them.

I suggest you to use LINQ to XML. With Enumerable.Sum for each utility element select sum of it's cities population:

var xdoc = XDocument.Load(path_to_xml);
var ns = xdoc.Root.GetDefaultNamespace();
var query = from u in xdoc.Root.Elements(ns + "DetailedUtility")
            select new
            {
                UtilityId = (int)u.Attribute("UtilityId"),
                TotalPopulation = u.Elements(ns + "City")
                                   .Sum(c => (int)c.Attribute("Population"))
            };

Returns:

{ UtilityId = 720, TotalPopulation = 104038 }
{ UtilityId = 721, TotalPopulation = 56760 }

This should do it:

    var xml = "all your xml";
    var doc = XDocument.Parse(xml); //or XDocument.Load for loading from a stream
    var sum = doc.Root.Elements("DetailedUtility").Select(element => new
    {
        Id = element.Attribute("UtilityId"),
        Population = element.Elements("City").Sum(e => int.Parse(e.Attribute("Population").Value))
    });

I have tested this piece of code. It works fine. Let me know if u face any issues.

  XmlReader reader = XmlReader.Create("D:\\\\population.xml"); List<string> Utility_id = new List<string>(); List<int> population = new List<int>(); int i=0; while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { if (reader.Name == "DetailedUtility") { Utility_id.Add(reader.GetAttribute(0)); population.Add(0); i++; } if (reader.Name == "City") { population[i-1] += Convert.ToInt32(reader.GetAttribute(1)); } } } for (i = 0; i < Utility_id.Count; i++) { Console.WriteLine("Utility ID = " + Utility_id[i] + "\\t Population = " + population[i]); } Console.ReadLine(); 

Regards, Prajul G

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