有以下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>
这是我得到的结果!
答案 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"))
//...
答案 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返回找到的第一个元素。当没有找到元素时,请注意返回的空指针。