使用Linq将xml转换为类

时间:2012-12-06 14:11:54

标签: c# linq

我正在使用LINQ将XML文件转换为我创建的类。无论我在尝试什么,我都会在列表中获得0。

List<UpdateMember> updateMembers = new List<ExeTeam.UpdateMember>();
updateMembers = GetMember(doc);
try
{
  IEnumerable<UpdateMember> member = from r in doc.Descendants("UpdateMember").Descendants("member")
  select new UpdateMember()
  {
    Birthdate = (string)(r.Element("Birthdate")) == string.Empty ? DateTimeParser((DateTime)(r.Element("Birthdate"))) : DateTime.Now,
    Email = (string)r.Element("Email") != null ? (string)r.Element("Email") : "",
    FamilyStatus = (string)r.Element("Familystatus") != null ? (string)r.Element("Familystatus") : "",
    ID = (int)r.Element("IdNumber") != 0 ? (int)r.Element("IdNumber") : 0,
    Phone1 = (int)r.Element("Telephone1") != 0 ? (int)r.Element("Telephone1") : 0,
    Phone2 = (int)r.Element("Telephone2") != 0 ? (int)r.Element("Telephone2") : 0,
    phone3 = (int)r.Element("Telephone3") != 0 ? (int)r.Element("Telephone3") : 0
  };
  return member.ToList();
}

xml

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
  <UpdateMember xmlns="http://tempuri.org/">
    <member>
      <Birthdate>25122012</Birthdate>
      <Email>fake@testing.com</Email>
      <Familystatus>single</Familystatus>
      <IdNumber>12345678</IdNumber>
      <Telephone1>123-4567890</Telephone1>
      <Telephone2></Telephone2>
      <Telephone3></Telephone3>
    </member>
  </UpdateMember>

from r in doc.Decendants("")...行中 我尝试过各种各样的变化。 谢谢所有

1 个答案:

答案 0 :(得分:4)

问题是命名空间:

<UpdateMember xmlns="http://tempuri.org/">

这意味着默认情况下,所有元素都在该命名空间中。您的查询都试图在命名空间中查找不是的元素,例如

Element("Familystatus")

这很容易在LINQ to XML中修复:

XNamespace ns = "http://tempuri.org/";
IEnumerable<UpdateMember> member = from r in doc.Descendants(ns + "UpdateMember")
                                                .Descendants(ns + "member")
// etc

此外,您尝试处理缺失的数据将无法正常工作,并且过于复杂。例如,这个:

Phone1 = (int)r.Element("Telephone1") != 0 ? (int)r.Element("Telephone1") : 0

应该是:

Phone1 = (int?) r.Element(ns + "Telephone1") ?? 0

如果转换为int,如果值丢失,则不会给出值0 - 它会抛出异常。转换为int?会改为使用空值。

我会将您的整个代码更改为:

return doc.Descendants(ns + "UpdateMember").Descendants(ns + "member")
          .Select (r => new UpdateMember
          {
              // Really? This is an odd default.
              Birthdate = (DateTime?) r.Element(ns + "Birthdate") ?? DateTime.Now,
              Email = (string) r.Element(ns + "Email") ?? "",
              FamilyStatus = (string) r.Element(ns + "Familystatus) ?? "",
              ID = (int?) r.Element(ns + "IDNumber") ?? 0,
              Phone1 = (int?) r.Element(ns + "Telephone1") ?? 0,
              Phone2 = (int?) r.Element(ns + "Telephone2") ?? 0,
              Phone3 = (int?) r.Element(ns + "Telephone3") ?? 0)
          })
          .ToList();

编辑:正如评论中所述,将电话号码存储为int值是一个非常糟糕的主意。你会丢失任何格式,你会丢失前导零,而且我希望很多完整的电话号码都在int的范围之外。我会将它们保留为字符串。