LINQ类型预计

时间:2013-03-04 17:27:57

标签: c# xml linq

有以下linq代码,尝试将xml文件解析为数据表,但我在结果数据表中得到奇怪的值,所有单元格值显示为

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

7 个答案:

答案 0 :(得分:5)

您忘记检索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
};

答案 1 :(得分:4)

address.Elements("Name")是“名称”类型的所有元素的集合。碰巧的是,在你的情况下,它是一个大小为1的集合,但它仍然是一个集合。您希望从该集合中获取第一个项目(因为您知道它将是唯一的一个),然后获取该元素的文本值。如果您使用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
        };

答案 2 :(得分:1)

这对你有什么用?

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

http://msdn.microsoft.com/en-us/library/bb155263.aspx

答案 3 :(得分:1)

您正在调用Elements,它返回包含在帮助程序类中的n个元素。

你可能打算调用Element,它将第一个元素作为XElement对象返回。

答案 4 :(得分: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

答案 5 :(得分:1)

address.Elements("Name")更改为address.Elements("Name").FirstOrDefault(),依此类推。

答案 6 :(得分: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;
    }

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