[英]LINQ to XML query returning wrong data
我有這個XML
<?xml version="1.0" encoding="utf-8" ?>
<Departments>
<Department>
<id>001</id>
<Section>
<SectionId>001001</SectionId>
<Room>
<RoomID>001001001</RoomID>
<Owner>guest1</Owner>
</Room>
<Room>
<RoomID>001001002</RoomID>
<Owner>guest11</Owner>
</Room>
</Section>
<Section>
<SectionId>001002</SectionId>
<Room>
<RoomID>001002001</RoomID>
<Owner>guest2</Owner>
</Room>
</Section>
</Department>
</Departments>
這是我使用Linq to Xml的代碼
var xDoc = XDocument.Load(inputUrl);
var sections = from el in xDoc.Descendants("Department")
where el.Element("id").Value.Equals("001")
select el.Element("Section");
var rooms = from el in sections
where el.Element("SectionId").Value.Equals("001001")
select el.Element("Room");
var roomsList = (from el in rooms
select new Room
{
roomID = (string)el.Element("RoomID"),
owner = (string)el.Element("Owner")
}).ToList();
我的問題是列表中只有1個房間,但我應該有2個房間。還請告知這是否是使用LINQ到xml的正確方法,我對LINQ還是很陌生。
將sections
和rooms
查詢更改為:
var sections = xDoc.Descendants("Department")
.FirstOrDefault(x => (string)x.Element("id") == "001")
.Elements("Section");
var rooms = sections.Where(x => (string)x.Element("SectionId") == "001001")
.Elements("Room");
有了這些,您將獲得2個房間。
為什么您的代碼不起作用?
select el.Element("Section")
只選擇第一section
中的元素Department
-你永遠無法從獲得的房間section
與id == "001002"
rooms
查詢中select el.Element("Room")
在每個匹配部分中僅返回第一個房間。 您可以將Element
更改為Elements
並添加其他SelectMany(x => x)
調用,以使基於語法的查詢正常工作:
var sections = from el in xDoc.Descendants("Department")
where el.Element("id").Value.Equals("001")
select el.Elements("Section");
var rooms = from el in sections.SelectMany(x => x)
where el.Element("SectionId").Value.Equals("001001")
select el.Elements("Room");
var roomsList = (from el in rooms.SelectMany(x => x)
select new
{
roomID = (string)el.Element("RoomID"),
owner = (string)el.Element("Owner")
}).ToList();
作為其他答案的替代方法 ,您可以使用Extensions.XPathSelectElements方法(XNode,字符串) (確保將using System.Xml.XPath
指令添加到文件頂部):
string
departmentId = "001",
sectionId = "001001";
var xDoc = XDocument.Load(inputUrl);
var rooms = xDoc.XPathSelectElements(
String.Format(
"//Department[id={0}]/Section[SectionId={1}]/Room",
departmentId,
sectionId))
.Select(el => new Room
{
roomID = (string)el.Element("RoomID"),
owner = (string)el.Element("Owner")
}).ToList();
這是自己的偏好問題。 我發現這寫起來更短,更容易閱讀。
只是為了證明有很多方法可以給貓皮:
var xDoc = XDocument.Load(@"C:\TEST\TEST.XML");
var depts = from e in xDoc.Descendants("Department")
where e.Element("id").Value.Equals("001")
select e;
var sections = from e in depts.Descendants("Section")
where e.Element("SectionId").Value.Equals("001001")
select e;
var rooms = (from e in sections.Descendants("Room")
select new //Room
{
ID = (string)e.Element("RoomID"),
Owner = (string)e.Element("Owner")
}).ToList();
如果您更改:
select el.Element("Room");
至
select el.Elements("Room");
您只在中間查詢中選擇一個房間,它應該是.Elements(...)
(請注意結尾的s
):
var rooms = from el in sections
where el.Element("SectionId").Value.Equals("001001")
select el.Elements("Room");
這同樣適用於您的section
查詢。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.