使用linq到xml创建复合对象

时间:2010-04-05 23:41:33

标签: c# linq

我正在阅读一个简单的xml文档,示例在这里:

<people>
  <person>
    <name>joe</name>
    <age>21</age>
    <contact>
      <phone-nums>
        <phone-num>
          <number>123-4567</number>
          <type>home</type>
        </phone-num>
        <phone-num>
          <number>123-4567</number>
          <type>office</type>
        </phone-num>
      </phone-nums>
    </contact>
  </person>
</people>

我使用HttpContent.ReadAsXElement()读取它,然后使用Linq创建对象。我的简单对象看起来像这样:

public class PeopleList : List<Person> { }

public class Person
{
    public string name;
    public int age;
    public Contact contact;
}

public class Contact
{
   public PhoneList phones;
}

public class PhoneList : List<Phone>{}

public class Phone
{
    public string number;
    public string type;
}

好的,所以现在我的班级里面都读到了我所挂断的地方(这是我代码中的扩展方法):

public PeopleList ReadAsPeopleList(this HttpContent content)
    {
        var people = content.ReadAsXElement();

        var personQuery = from p in people.Elements("person")
            select new Person()
            {
                name = p.Element("name").ValueOrDefault(),
                age = p.Element("age").ValueOrDefault(),
                contact = (from c in p.Elements("contact")
                    select new Contact()
                    {
                         //I don't know how to select a new list of phones into a contact here
                    }
            };

        PeopleList l = new PeopleList();
        l.AddRange(personQuery);
        return l;
    }

我在使用复合电话号码列表创建联系人类型时遇到问题。任何帮助将不胜感激。

注意:我在这里重写了所有这些的简化版本

2 个答案:

答案 0 :(得分:0)

要获取需要进入联系人的“电话”集合,您可以使用:

c.Elements("phone-num").Select(phone => new Phone()
    {
        number = phone.Element("number").Value,
        type = phone.Element("type").Value
    });

所以你想要

select new Contact() 
{ 
    PhoneList = c.Elements("phone-num").Select(phone => new Phone()
        {
            number = phone.Element("number").Value,
            type = phone.Element("type").Value
        })
}

答案 1 :(得分:0)

这个答案会与您的实际问题略有不同,但可能会为您的最终解决方案提供一些方向。

考虑为您的馆藏使用List<T>而不是创建BusinessObjectCollection : List<T>。这是一个很有用的SO读物:List or BusinessObjectCollection?

话虽如此,这是你的课程的一个稍微调整过的版本;我也使用了属性而不是字段。最后,因为我没有使用过很多HTTPContext,所以我使用基本字符串将一个例子放在一起。这里介绍的方法应该很容易转换为HTTPContext的扩展方法,但是:

public static IEnumerable<Person> ReadAsPeopleList( string xml )
{
    var doc = XDocument.Parse( xml );

    var people = doc.Root.Elements( "person" )
        .Select( x => new Person
        {
            Name = x.Element( "name" ).Value,
            Age = int.Parse( x.Element( "age" ).Value ),
            Contact = new Contact
            {
                Phones = x.Descendants( "phone-num" )
                .Select( p => new Phone
                {
                    Number = p.Element( "number" ).Value,
                    Type = p.Element( "type" ).Value
                } )
            }
        }
        );

    return people;
}

private static string MyXml = @"
<people><person><name>joe</name><age>21</age><contact><phone-nums>
<phone-num><number>123-4567</number><type>home</type></phone-num>
<phone-num><number>123-4567</number><type>office</type></phone-num>
</phone-nums></contact></person><person><name>bill</name><age>30</age>
<contact><phone-nums><phone-num><number>123-4567</number><type>home</type>
</phone-num><phone-num><number>123-4567</number><type>office</type>
</phone-num></phone-nums></contact></person></people>";