【问题标题】:c# linq to xml to listc# linq to xml to list
【发布时间】:2010-04-08 14:05:37
【问题描述】:

我想知道是否有一种方法可以将结果列表放入带有 linq to xml 的列表中。例如,如果我有以下 xml:

<?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 to 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 读起来很混乱。有没有办法可以从中获取字符串列表?

谢谢

【问题讨论】:

    标签: c# xml linq list linq-to-xml


    【解决方案1】:

    此查询有效 - 经过测试和验证:

    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”。

    【讨论】:

    • 如果你有一个没有type 属性的SportPage 元素,这将抛出一个对象空异常。
    • 解决了它,我删除了 LinkPage 后代和 SportPages 后代,因为感谢其他回复,我发现它可以自动搜索 :) 非常感谢你们!
    【解决方案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);
    

    【讨论】:

    • 但是你忽略了sportpage.Attribute("type").Value == "Karate"的条件
    【解决方案3】:

    你是这个意思吗?

    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();
    

    【讨论】:

    • 我得到:“错误:无法将类型 'System.Collections.Generic.List>' 隐式转换为 'System .Collections.Generic.List'"
    • 另外你需要更加小心你的大写和小写:例如此语句不起作用:.Where( anySportPage =&gt; anySportpage. - 您需要在两种情况下使用相同的大小写!! anySportPage vs. anySportpage - 不一样!
    • 出生于不测试并假设我知道.Elements() 的结果。 (使用var IDs 会起作用,但我从来没有真正喜欢过var。)感谢您的更正,并写下正确的答案。 :)
    【解决方案4】:

    我认为您发现“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();
    

    【讨论】:

      【解决方案5】:

      您遇到的最大问题是您没有从返回的元素集中获取.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;
      

      【讨论】:

      • 这种方式比较懒。如果您有明确的模式,则可以使用与问题示例中相同的内容。您只需在您的选择语句的末尾添加一个.Value。
      猜你喜欢
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 1970-01-01
      • 2013-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多