2013-03-04 61 views
4

有以下LINQ代码,试图解析XML文件的数据表,但我得到的数据表中的所有单元格值时得到奇怪的值显示为LINQ类型预期

System.Xml.Ling.XContainer+<GetElements>d_11 

这里是我的LINQ

  XDocument doc1 = XDocument.Load(@"D:\m.xml"); 
      var q = from address in doc1.Root.Elements("Address") 
        let name = address.Elements("Name") 
        let street = address.Elements("Street") 
        let city = address.Elements("city") 
        select new 
        { 
         Name = name, 
         Street = street, 
         City = city 
        }; 

      var xdt = new DataTable(); 

      xdt.Columns.Add("Name", typeof(string)); 
      xdt.Columns.Add("Street", typeof(string)); 
      xdt.Columns.Add("City", typeof(string)); 

      foreach (var address in q) 
      { 
       xdt.Rows.Add(address.Name, address.Street, address.City); 
      } 

      dataGrid1.ItemsSource = xdt.DefaultView; 

这里是我的xml:

<PurchaseOrder PurchaseOrderNumber="99503" OrderDate="1999-10-20"> 
    <Address Type="Shipping"> 
    <Name>Ellen Adams</Name> 
    <Street>123 Maple Street</Street> 
    <City>Mill Valley</City> 
    <State>CA</State> 
    <Zip>10999</Zip> 
    <Country>USA</Country> 
    </Address> 
    <Address Type="Billing"> 
    <Name>Tai Yee</Name> 
    <Street>8 Oak Avenue</Street> 
    <City>Old Town</City> 
    <State>PA</State> 
    <Zip>95819</Zip> 
    <Country>USA</Country> 
    </Address> 
</PurchaseOrder> 

这里是结果我得到! enter image description here

回答

5

你忘了regrieve XElements内文本,以便您选择与属性等全要素使用这部分代码:

var q = from address in doc1.Root.Elements("Address") 
let name = address.Element("Name") 
let street = address.Element("Street") 
let city = address.Element("city") 
select new 
{ 
    Name = name.Value, 
    Street = street.Value, 
    City = city.Value 
}; 
4

address.Elements("Name")集合中的所有类型为 “姓名” 的元素的。恰巧在你的情况下它是一个大小的集合,但它仍然是一个集合。您想从该集合中获取第一个项目(因为您知道它将是唯一的项目),然后获取该元素的文本值。如果您使用Element而不是Elements,您将获得匹配的第一个项目,而不是项目集合。

现在你有了你的单一元素,你还需要获取该元素的值,而不是元素本身(在一般情况下也包含大量其他信息,即使没有其他的东西。有趣的是在这种特殊情况下

var q = from address in doc1.Root.Elements("Address") 
     select new 
     { 
      Name = address.Element("Name").Value, 
      Street = address.Element("Street").Value, 
      City = address.Element("City").Value 
     }; 
1

你正在呼叫Elements哪个返回包装在辅助类中的n个元素。

您可能的意思是致电Element,它返回第一个元素作为XElement对象。

1

试试这个:

var q = from address in doc1.Root.Elements("Address") 
     let name = address.Element("Name").Value 
     let street = address.Element("Street").Value 
     let city = address.Element("City").Value 
1

变化address.Elements("Name")address.Elements("Name").FirstOrDefault()等。

1

Elements方法返回一个IEnumerable。因此,你的let变量指向一系列元素,而不是单个元素。您应该返回返回的单个元素,它将是一个XElement,然后将其Value属性获取其内容的连接文本。 (按文档)

而不是


        select new 
        { 
         Name = name, 
         Street = street, 
         City = city 
        } 

你应该写:


        select new 
        { 
         Name = name.Single().Value, 
         Street = street.Single().Value, 
         City = city.Single().Value 
        } 
在let表达式

要么有,或直接。如果你希望使用的成员访问语法


    public static string StringValueOfElementNamed(XElement node, string elementName) { 
     return node.Elements(elementName).Single().Value; 
    } 

打开这个辅助方法为扩展方法:您也可以找到一个辅助方法是有用的。

编辑:阅读并发答案后,用更好的方法是:


    public static string StringValueOfElementNamed(XElement node, string elementName) { 
     return node.Element(elementName).Value; 
    } 

元素返回找到的第一个元素。当没有找到元素时,请注意返回空指针。

相关问题