2010-04-08 185 views
4

我想知道是否有办法将结果列表与linq to xml结合到列表中。如果我会有以下xml例如:c#linq to xml to list

<?xml version="1.0"?> 
<Sports xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <SportPages> 
     <SportPage type="test"> 
      <LinkPage> 
       <IDList> 
        <string>1</string> 
        <string>2</string> 
       </IDList> 
      </LinkPage> 
     </SportPage> 
    </SportPages> 
</Sports> 

我怎么能从IDList中获取字符串列表?

我是相当新的LINQ到XML,所以我只是尝试一些东西出来,我目前在这一点上:

var IDs = from sportpage in xDoc.Descendants("SportPages").Descendants("SportPage") 
         where sportpage.Attribute("type").Value == "Karate" 
         select new 
         { 
          ID = sportpage.Element("LinkPage").Element("IDList").Elements("string") 
         }; 

但VAR是混乱体面地阅读。没有办法,我可以从这里得到一个字符串列表?

感谢

回答

6

此查询的工作 - 测试和验证:

var ID2 = (from sportpage in xDoc.Descendants("SportPages").Descendants("SportPage") 
      where sportpage.Attribute("type").Value == "Karate" 
      select sportpage) 
      .Descendants("LinkPage") 
      .Descendants("IDList") 
      .Elements("string") 
      .Select(d => d.Value) 
      .ToList(); 

给了我两个字符串列表, “1” 和 “2”。

+1

这会抛出如果你有一个没有'type'属性的'SportPage'元素,则为一个对象null异常。 – 2010-04-08 14:38:51

+0

解决了它,我删除了LinkPage后裔和SportPages后裔,因为感谢其他答复我想出了它autosearches :)所以非常感谢你的所有! – WtFudgE 2010-04-08 14:48:43

2
var myStrings = xDoc.Descendants("SportPage") 
        .Where(d => d.Attribute("type").Value == "Karate") 
        .Descendants("IDList") 
        .Descendants("string") 
        .Select(d => d.Value); 

看到您的字符串:

xDoc.Descendants("SportPage") 
    .Descendants("IDList") 
    .Where(d => d.Attribute("type").Value == "Karate") 
    .Descendants("string") 
    .Select(d => d.Value) 
    .ToList() 
    .ForEach(Console.WriteLine); 
+1

但你忽略的条件'sportpage.Attribute(“类型”)值==“空手道”' – 2010-04-08 14:20:51

1

你的意思呢?

List<string> IDs = xDoc.Descendants("SportPages").Descendants("SportPage") 
    .Where(anySportPage => anySportpage.Attribute("type").Value == "Karate") 
    .Select(karateSportPage => karateSportpage.Element("LinkPage").Element("IDList").Elements("string")) 
    .ToList(); 
+0

我得到:“错误:无法隐式转换类型“System.Collections.Generic。列出>'到'System.Collections.Generic.List '' – 2010-04-08 14:26:30

+0

你还需要对你的大写和小写更小心:例如这个声明不起作用:'.Where(anySportPage => anySportpage。' - 你需要在两种情况下使用相同的套管!!'anySportPage vs. anySportpage' - 不完全相同! – 2010-04-08 14:27:50

+0

由于没有测试并假设我知道(.'lement()'。(使用'var IDs'可以工作,但我从不真正喜欢'var')。)感谢您的更正,并写下正确的答案。:) – ANeves 2010-04-08 14:55:57

0

我认为你找到“var”混沌的原因是你在你的选择中创建了“new”的匿名类型。如果你只选择了你之后的一个项目,那么这个var不会是一个匿名类型。

例如

select sportpage.Element("LinkPage").Element("IDList").Elements("string"); 

但是,我的选择是使用。这样的符号。

List<string> ids = xDoc.Elements("SportPages").Elements("SportPage").Where(sportPage => sportPage.Attribute("type").Value == "Karate").Elements("LinkPage").Elements("IDList").Elements("string").Select(id => id.Value).ToList(); 
0

您遇到的最大问题是您没有从返回的元素集中获取.Value。但这是另一种方法。

var ids = from sportPage in xDoc.Descendants("SportPage") 
      let attrib = sportPage.Attribute("type") 
      where attrib != null 
      let type = attrib.Value 
      where !string.IsNullOrEmpty(type) 
       && type == "Karate" 
      from id in sportPage.Descendants("IDList").Elements() 
      select id.Value; 
+0

这种方式很懒惰。如果你有一个明确的模式,你可以在你的示例中使用与你问题中相同的东西。你只需要在选择的语句末尾添加一个'.Value'。 – 2010-04-08 14:45:26