无法从Yahoo!解析xml幻想体育用c#

时间:2014-01-02 16:10:09

标签: c# .net xml-parsing yahoo-api

我在网上进行了一些搜索,无法找到问题的原因,所以我很抱歉,如果已经以另一种形式询问我,我只是不明白。

我的问题是我正在尝试解析从Yahoo!检索到的XML。幻想体育,但似乎没有任何工作。

我已将收到的XML(使用带有凭据的GET请求)转换为字符串。这是评估。

<?xml version="1.0" encoding="UTF-8" ?> 
- <fantasy_content xml:lang="en-US" yahoo:uri="http://fantasysports.yahooapis.com/fantasy/v2/game/223/players"     xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" time="5489.1560077667ms" copyright="Data provided by Yahoo! and STATS, LLC" refresh_rate="60"     xmlns="http://fantasysports.yahooapis.com/fantasy/v2/base.rng">
- <game>
  <game_key>223</game_key> 
  <game_id>223</game_id> 
  <name>Football PLUS</name> 
  <code>pnfl</code> 
  <type>full</type> 
  <url>http://football.fantasysports.yahoo.com/f2</url> 
  <season>2009</season> 
- <players count="25">
- <player>
  <player_key>223.p.8261</player_key> 
  <player_id>8261</player_id> 
- <name>
  <full>Adrian Peterson</full> 
  <first>Adrian</first> 
  <last>Peterson</last> 
  <ascii_first>Adrian</ascii_first> 
  <ascii_last>Peterson</ascii_last> 
  </name>
  <editorial_player_key>nfl.p.8261</editorial_player_key> 
  <editorial_team_key>nfl.t.16</editorial_team_key> 
  <editorial_team_full_name>Minnesota Vikings</editorial_team_full_name> 
  <editorial_team_abbr>Min</editorial_team_abbr> 
- <bye_weeks>
  <week>9</week> 
  </bye_weeks>
  <uniform_number>28</uniform_number> 
  <display_position>RB</display_position> 
- <headshot>
<url>http://l.yimg.com/iu/api/res/1.2/7gLeB7TR77HalMeJv.iDVA--/YXBwaWQ9eXZpZGVvO2NoPTg2MDtjcj0xO2N3PTY1OTtkeD0xO2R5PTE7Zmk9dWxjcm9wO2g9NjA7cT0xMDA7dz00Ng--/http://l.yimg.com/j/assets/i/us/sp/v/nfl/players_l/20120913/8261.jpg</url> 
  <size>small</size> 
  </headshot>
  <image_url>http://l.yimg.com/iu/api/res/1.2/7gLeB7TR77HalMeJv.iDVA--/YXBwaWQ9eXZpZGVvO2NoPTg2MDtjcj0xO2N3PTY1OTtkeD0xO2R5PTE7Zmk9dWxjcm9wO2g9NjA7cT0xMDA7dz00Ng--/http://l.yimg.com/j/assets/i/us/sp/v/nfl/players_l/20120913/8261.jpg</image_url> 
  <is_undroppable>1</is_undroppable> 
  <position_type>O</position_type> 
- <eligible_positions>
  <position>RB</position> 
  </eligible_positions>
  <has_player_notes>1</has_player_notes> 
  </player>
- <player>
  </players>
  </game>
  </fantasy_content>

我尝试的两种方法是这些(请注意:“xmlContent”是包含上面列出的XML的字符串):

1.)
XDocument chicken = XDocument.Parse(xmlContent);
var menus = from menu in chicken.Descendants("name")
select new
{
ID = menu.Element("name").Value,
};

2.)
byte[] encodedString = Encoding.UTF8.GetBytes(xmlContent);
MemoryStream ms = new MemoryStream(encodedString);

XmlDocument doc = new XmlDocument();
doc.Load(ms);

foreach (XmlNode row in doc).SelectNodes("//fantasy_content"))
{}

基本上,我没有列举任何结果。我有一种感觉,我错过了一些关键步骤。任何帮助是极大的赞赏。谢谢大家。

更新

根据我收到的很棒的建议,我尝试了三件事。由于它不能正常工作,我听不太清楚。 :)实际上,这是半准确的,请忍受我在这里使用XML的新手尝试,因为我真的很感谢回复。以下是我如何搞砸了这些伟大的建议,你能否提供我错过的另一个提示?再次感谢大家。

根据Jon Skeet的建议(这对我没有任何结果):

1.) XNamespace ns = "http://fantasysports.yahooapis.com/fantasy/v2/base.rng";
XDocument chicken = XDocument.Parse(xmlContent);
var menus = from menu in chicken.Descendants(ns + "fantasy_content")
select new
{
ID = menu.Element("name").Value,
};

根据第二个建议(这会引发错误):

2.) var result = XElement.Load(xmlContent).Descendants().Where(x => x.Name.LocalName == "name");

根据建议我需要识别名称空间和Yahoo!的组合指南:http://developer.yahoo.com/dotnet/howto-xml_cs.html

3.)     xmlContent = oauth.AcquirePublicData(rtUrl, "GET");

byte[] encodedString = Encoding.UTF8.GetBytes(xmlContent);

MemoryStream ms = new MemoryStream(encodedString);

XmlDocument doc = new XmlDocument();
doc.Load(ms);

XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("fantasy_content", "http://fantasysports.yahooapis.com/fantasy/v2/base.rng");
XmlNodeList nodes = doc.SelectNodes("/name", ns);

foreach (XmlNode node in nodes)
{
}

2 个答案:

答案 0 :(得分:4)

这就是你的绊倒:

xmlns="http://fantasysports.yahooapis.com/fantasy/v2/base.rng"

您要求未命名的命名空间中的元素 - 但元素默认为上面显示的命名空间。

在LINQ to XML中很容易解决(在XmlDocument中可行但不那么简单)

XNamespace ns = "http://fantasysports.yahooapis.com/fantasy/v2/base.rng";
var menus = chicken.Descendants(ns + "name")
                   ...

请注意,在您的原始方法中,您实际上在 name元素中寻找name元素 - 这不会起作用,但命名空间部分可能已足够让你去。

编辑:目前尚不清楚你为什么要使用匿名类型,但如果你真的希望文档中的所有name元素值作为匿名类型实例中的ID属性,只需使用:

XNamespace ns = "http://fantasysports.yahooapis.com/fantasy/v2/base.rng";
var menus = chicken.Descendants(ns + "name")
                   .Select(x => new { ID = x.Value });

请注意,不需要使用Descendants(ns + "fantasy_content"),因为只需选择根元素。

答案 1 :(得分:0)

元素名称由两部分组成:xmlns(命名空间)和 localname 。如果缺少xmlns,则name等于本地名称。因此,您必须使用命名空间创建名称或忽略它

您可以忽略LINQ中的命名空间,只需使用LocalName

   var result = XElement.Load(@"C:\fantasy_content.xml")
        .Descendants()
        .Where(x => x.Name.LocalName == "name")
        .ToList();