4

有以下 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>

这是我得到的结果! 在此处输入图像描述

4

7 回答 7

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
};
于 2013-03-04T17:32:13.450 回答
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
        };
于 2013-03-04T17:31:33.417 回答
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

于 2013-03-04T17:30:24.937 回答
1

您正在调用Elementswhich 返回包装在帮助器类中的 n 个元素。

您可能的意思是调用Elementwhich 将第一个元素作为XElement对象返回。

于 2013-03-04T17:32:46.393 回答
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
于 2013-03-04T17:33:02.713 回答
1

改成等等address.Elements("Name")address.Elements("Name").FirstOrDefault()

于 2013-03-04T17:36:35.953 回答
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 返回第一个找到的元素。注意没有找到元素时返回的空指针。

于 2013-03-04T17:38:51.130 回答