【问题标题】:Get the Count of Elements where candidate has won获取候选人获胜的元素计数
【发布时间】:2010-03-10 05:43:37
【问题描述】:

LINQ2Xml: 我想知道候选人在每个省赢得的元素的数量。我需要一些帮助。

<Pronvice_Data>
    <Pronvice>PronviceA</Pronvice>
    <Registered_Voters>115852</Registered_Voters>
    <Sam_Kea>100</Sam_Kea>
    <Jeje>500</Jeje>
    <John_Doe>400</John_Doe>
</Pronvice_Data>

<Pronvice_Data>
    <Pronvice>PronviceA</Pronvice>
    <Registered_Voters>25852</Registered_Voters>
    <Sam_Kea>200</Sam_Kea>
    <Jeje>100</Jeje>
    <John_Doe>300</John_Doe>
</Pronvice_Data>

<Pronvice_Data>
    <Pronvice>PronviceC</Pronvice>
    <Registered_Voters>317684</Registered_Voters>
    <Sam_Kea>1000</Sam_Kea>
    <Jeje>1200</Jeje>
    <John_Doe>190</John_Doe>
</Pronvice_Data>

预期结果:

Candidate | Won In
Jeje         2
John_Doe     1
Sam_Kea      0   

【问题讨论】:

  • 您好,您使用的是哪种编程语言?到目前为止你尝试了什么?你得到什么样的错误?
  • XML 不包含根 XML 节点的任何原因?这使得使用需要路由节点的System.Xml.Linq.XDocument 变得困难。

标签: .net xml linq-to-xml


【解决方案1】:

好的,我不喜欢数据格式,所以我把它改成这样:

<root>
  <Candidates>
    <Sam_Kea/>
    <Jeje/>
    <John_Doe/>
  </Candidates>

  <Provinces>
    <Province name='ProvinceA' Registered_Voters='115852'>
      <Candidate name='Sam_Kea' votes='100'/>
      <Candidate name='Jeje' votes='500'/>
      <Candidate name='John_Doe' votes='400'/>
    </Province>

    <Province name='ProvinceB' Registered_Voters='25852'>
      <Candidate name='Sam_Kea' votes='200'/>
      <Candidate name='Jeje' votes='100'/>
      <Candidate name='John_Doe' votes='300'/>
    </Province>

    <Province name='ProvinceC' Registered_Voters='317684'>
      <Candidate name='Sam_Kea' votes='1000'/>
      <Candidate name='Jeje' votes='1200'/>
      <Candidate name='John_Doe' votes='190'/>
    </Province>
  </Provinces>

</root>

这是我使用的 LINQ-to-XML 代码:

public void Run()
{
    string fileToLoad = this.GetType().Name + ".xml";

    XElement root = XElement.Load(fileToLoad);

    // =======================================================
    System.Console.WriteLine("\nCandidates:");
    var allCandidates = from c in root.Element("Candidates").Elements()
        select c.Name;

    foreach (var d in allCandidates)
        Console.WriteLine("  {0}", d.ToString());


    // =======================================================
    System.Console.WriteLine("\nNumber of Candidates in each Province:");

    var s1 = from p in root.Element("Provinces").Elements()
        select new
            {
                Prov = (string) p.Attribute("name"),
                NumCandidates = p.Elements("Candidate").Count()
            };

    foreach (var d in s1)
        Console.WriteLine("  {0}", d.ToString());


    // =======================================================
    System.Console.WriteLine("\nCandidate with most votes:");
    var s2 = from p in root.Element("Provinces").Elements()
        let maxVotes = (from c in p.Elements("Candidate") select c)
                       .Max(x => ((int)x.Attribute("votes")))

        select new
            {
                Prov = (string) p.Attribute("name"),
                Voters = (int) p.Attribute("Registered_Voters"),
                Candidate = (from c in p.Elements("Candidate")
                             select c).Where(x => ((int)x.Attribute("votes")) == maxVotes)
                    .First().Attribute("name").Value
            };

    foreach (var d in s2)
        Console.WriteLine("  {0}", d.ToString());


    // =======================================================
    System.Console.WriteLine("\nCandidates and the # of provinces won:");

    var s4 = from can in allCandidates
        let count = (from p in s2 where p.Candidate == can select p).Count()
        orderby count descending
        select new { Candidate = can, NumberOfProvincesWon = count };

    foreach (var d in s4)
        Console.WriteLine("  {0}", d.ToString());
}

输出:

Candidates:
  Sam_Kea
  Jeje
  John_Doe

Number of Candidates in each Province:
  { Prov = ProvinceA, NumCandidates = 3 }
  { Prov = ProvinceB, NumCandidates = 3 }
  { Prov = ProvinceC, NumCandidates = 3 }

Candidate with most votes:
  { Prov = ProvinceA, Voters = 115852, Candidate = Jeje }
  { Prov = ProvinceB, Voters = 25852, Candidate = John_Doe }
  { Prov = ProvinceC, Voters = 317684, Candidate = Jeje }

Candidates and the # of provinces won:
  { Candidate = Jeje, NumberOfProvincesWon = 2 }
  { Candidate = John_Doe, NumberOfProvincesWon = 1 }
  { Candidate = Sam_Kea, NumberOfProvincesWon = 0 }

【讨论】:

  • 非常感谢,这对我有帮助。你的格式很好,但这意味着我必须重新创建它。
  • 您问题中 XML 结构的挑战是,程序如何区分候选名称和另一个 XML 元素?例如Registered_Voters 是文档中的一个元素,它的文本值是一个整数。 Sam_Kea 也是如此。其中只有一个是候选人。哪一个?您问题中的 XML 结构似乎有点“松散”。
  • 非常感谢 Cheeso。我让它为我工作。虽然它们是核心 linq 表达式!你如何轻松地让他们工作。现在,我需要得到每个候选人获胜的百分比。
  • 嗨,我怎样才能让百分比起作用。我的实际百分比应该是 (Total_Vote_Cast_For_Candidate_in_all_Provinces/Total_Votes_Cast_In All_Pronvinces) * 100
  • 是的,这是一个新问题,但属于原始问题。我只是在总和上失败了。帮助。
【解决方案2】:

我很难处理属性值。 从原始格式,我会使用下面的代码得到它。

var Percentages= from elem in xmlVectors2.Descendants("Province_Data")
          where elem.Elements().Count() > 1
          group elem by new { groupedData = elem.Element("Province_Data")} into g
          let votesSam_Kea=g.Sum(elem =>(int)elem.Element("Sam_Kea"))
          let votesJeje=g.Sum(elem =>(int)elem.Element("Jeje"))
          let votesJohn_Doe= g.Sum(elem =>(int)elem.Element("John_Doe"))              
          let totVotesCast=votesSam_Kea+ votesJeje+ votesJohn_Doe
          select new {
             Percent_Sam_Kea= Math.Round((double)(votesSam_Kea*100)/totVotesCast,2),
             Percent_Jeje=Math.Round((double)(votesJeje*100)/totVotesCast,2),
             Percent_John_Doe=Math.Round((double)(votesJohn_Doe*100)/totVotesCast,2),                
             VotesCast= totVotesCast,
             RegisteredVoters = g.Sum(elem => (int)elem.Element("Registered_Voters"))
             };

【讨论】:

    猜你喜欢
    • 2016-11-18
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    • 1970-01-01
    • 2020-04-21
    相关资源
    最近更新 更多