【问题标题】:C# Xml Linq, populate list of certain object typeC# Xml Linq,填充某些对象类型的列表
【发布时间】:2015-11-02 13:39:58
【问题描述】:

所以我试图将 Xml 文档填充到对象列表中,我设法检索单个节点,但问题是我想选择几个!

这是对象

public class Item
{
    public string Title{get;set;}
    public string Date{get;set;}
}

这里是 XML

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfFeed xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <XmlItem Name="Test">
    <Items>
      <SubItem>
        <Title>Some Title</Title>
        <Date>Fri, 30 Oct</Date>
      </SubItem>
      <SubItem>
        <Title>Some Title</Title>
        <Date>Fri, 30 Oct</Date>
      </SubItem>
    </items>
  </XmlItem>
</ArrayOfFeed>

这是我的代码。正如我之前所说,我设法只选择了 XML 中的第一个子项,我想全选。尝试使用它,但到目前为止没有成功。

var itemToFind = "Test"
XDocument doc = XDocument.Load(location);
IEnumerable<Item> result = (from c in doc.Descendants("XmlItem")
                               where c.Attribute("Name").Value == itemToFind
                               let r = c.Element("Items")
                               let z = r.Element("SubItem")

                               select new Item()
                               {
                                   Title = (string)z.Element("Title"),
                                   Date = (string)z.Element("Date"),
                               }).ToList();

return result;

非常感谢您的帮助:)

【问题讨论】:

  • 那么你当前的代码会发生什么?为什么要创建 FeedItem 类型的对象而不是 Item?为什么要分配给属性标题和日期而不是标题和日期?你为什么最后打电话给Cast&lt;Item&gt;().ToList()?您实际上是在寻找 SubItems 而不是 XmlItems? (您的 Item 类只有一个标题/日期,表明它属于 SubItem 而不是 XmlItem...)
  • 您的 XML 中是否存在多个具有 Name="Test" 属性的 XmlItem 元素?
  • 对不起,我不得不重写我的代码,以便更容易理解我想要什么,所以有一些拼写错误,现在应该更正。关于我最后的演员表,我只是把它扔在那里,因为它给了我例外。我正在寻找所有子项值,例如标题和日期,我想在 XmlElements 属性匹配的地方/如果 XmlElements 属性匹配时检索所有这些值,对不起,希望它更有意义:)
  • 如果您已经解决了您的问题,请将解决方案发布为答案而不是问题的更新,如果现有答案尚未涵盖该问题。

标签: c# xml linq list


【解决方案1】:

我对 XmlDocuments 比对 XDocuments 更熟悉,但我会这样做:

  • 将 XML 加载到 XmlDocument(文档)中
  • 使用SelectNodes 方法获取节点集合,参数为XPath 到您想要在集合中的节点 - 我假设您想要找到所有具有属性的XmlItem 节点的名称="测试"。
  • Foreach XmlNode 在该集合中(XmlNodeListSelectNodes 返回),您将需要使用 SelectNodes 来获取所有 SubItems 节点
  • 循环第二个集合(SubItems)并创建新项目,并使用 SelectSingleNode 方法获取 Title 和 Date 值。

【讨论】:

    【解决方案2】:

    试试这个。您的 Items 结束标记需要大写 I。我使用 ParseExact 将日期字符串转换为 DateTime。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    
    
    namespace ConsoleApplication1
    {
        class Program
        {
    
            static void Main(string[] args)
            {
                string xml =
                    "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                        "<ArrayOfFeed xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
                          "<XmlItem Name=\"Test\">" +
                            "<Items>" +
                              "<SubItem>" +
                                "<Title>Some Title</Title>" +
                                "<Date>Fri, 30 Oct</Date>" +
                              "</SubItem>" +
                              "<SubItem>" +
                                "<Title>Some Title</Title>" +
                                "<Date>Fri, 30 Oct</Date>" +
                              "</SubItem>" +
                            "</Items>" +
                          "</XmlItem>" +
                        "</ArrayOfFeed>";
                XDocument doc = XDocument.Parse(xml);
                string itemToFind = "Test";
    
                List<Item> items = doc.Descendants("XmlItem").Where(x => x.Attribute("Name").Value == itemToFind).Descendants("SubItem").Select(y => new Item
                {
                    Title = y.Element("Title").Value,
                    Date = DateTime.ParseExact(y.Element("Date").Value, "ddd, dd MMM", System.Globalization.CultureInfo.InvariantCulture)
                }).ToList();
    
            }
        }
        public class Item
        {
            public string Title { get; set; }
            public DateTime Date { get; set; }
        }
    
    
    }
    ​
    

    【讨论】:

    • 您错过了itemToFind 过滤器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-24
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多