使用LINQ选择特定的XML根目录

时间:2014-07-31 08:33:03

标签: c# xml linq

我遇到以下问题,我正在使用这种类型的XML结构:

<directory>

     <ContactDirectory header="Foo1">
        <Person name="Person 1" number="Person 2">
      </ContactDirectory>

      <ContactDirectory name="Foo2">
        <Person name="Person 2" number="Person 2">
      </ContactDirectory>
</directory>

目前,我正在使用字典并存储这些值:

var contacts = element.Descendants("Person").ToDictionary(datenum => datenum.Attribute("name").Value,
            datenum => datenum.Attribute("number").Value);

这可以找到并且在“元素”中只是通过结构。

问题在于:每当我这样做时,它只选择第一个XML根标签,而不考虑其他任何标签。

我想要发生的事情:每当用户选择要选择的目录时,都会显示此特定标头的XML并将其存储在字典中。

我试过:在第一次尝试时,我尝试使用一个带有WHERE子句的LINQ语句:

var selectedContacts = element.Descendants("Person").Where(element.Attribute("header").ToString() == "Foo1").Select(element.Attribute("name").Value);

然而这不起作用,并给我一个:`不包含'Where'的定义....

我哪里错了?附:我正在学习LINQ。

2 个答案:

答案 0 :(得分:3)

你应该以这种方式使用linq:

var selectedContacts = element.Descendants("Person")
                          .Where(x=>x.Parent.Attribute("name").Value == "Foo1")
                          .Select(x=>x.Attribute("name").Value);

转换为Dic:

var selectedContacts = element.Descendants("Person")
                          .Where(x=>x.Parent.Attribute("name").Value == "Foo1")
                          .ToDictionary(datenum => datenum.Attribute("name").Value,
                                        datenum => datenum.Attribute("number").Value);

答案 1 :(得分:0)

首先正确的xml是:

<?xml version="1.0" encoding="UTF-8"?>
<directory>
   <ContactDirectory name="Foo1">
      <Person name="Person 1" number="Person 2" />
   </ContactDirectory>
   <ContactDirectory name="Foo2">
      <Person name="Person 2" number="Person 2" />
   </ContactDirectory>
</directory>

编辑 - &gt; Paste Special - &gt; 粘贴为XML类 + refactor:

public class Master
{
    [XmlType(AnonymousType = true)]
    [XmlRoot(Namespace = "", IsNullable = false)]
    public partial class directory
    {
        [XmlElement("ContactDirectory")]
        public directoryContactDirectory[] ContactDirectory { get; set; }
    }
    [XmlType(AnonymousType = true)]
    public partial class directoryContactDirectory
    {
        public directoryContactDirectoryPerson Person { get; set; }
        [XmlAttribute()]
        public string name { get; set; }
    }
    [XmlType(AnonymousType = true)]
    public partial class directoryContactDirectoryPerson
    {
        [XmlAttribute()]
        public string name { get; set; }
        [XmlAttribute()]
        public string number { get; set; }
    }
}

代码示例:

        Master.directory directory;
        const string data = @"
            <?xml version='1.0' encoding='UTF-8'?>
            <directory>
               <ContactDirectory name='Foo1'>
                  <Person name='Person 1' number='Person 2' />
               </ContactDirectory>
               <ContactDirectory name='Foo2'>
                  <Person name='Person 2' number='Person 2' />
               </ContactDirectory>
            </directory>";
        if (data.Deserialize(out directory))
        {
            var contacts = directory.ContactDirectory.ToDictionary(
                o => o.name, 
                o => o.Person.number);
        }

扩展方法:

    public static bool Deserialize<T>(this String str, out T item)
    {
        item = default(T);
        bool success;
        try
        {
            var ser = new XmlSerializer(typeof(T));
            using (var reader = XmlReader.Create(new StringReader(str)))
            {
                item = (T)ser.Deserialize(reader);
            }
            success = true;
        }
        catch (Exception)
        {
            success = false;
        }

        return success;
    }