我有这个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();
我的问题是我只在列表中获得一个房间,但我应该得到两个。如果这是使用LINQ到xml的正确方法,请另外建议,我对LINQ来说还不够。
答案 0 :(得分:2)
将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"
获得空间
{li> select el.Element("Room")
在rooms
查询中仅返回每个匹配部分的第一个房间。
醇>
您可以将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();
答案 1 :(得分:2)
作为其他答案的替代方案,您可以使用Extensions.XPathSelectElements Method (XNode, String)(确保将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();
这是一个自己喜欢的问题。我觉得这写得更短更容易阅读。
答案 2 :(得分:1)
只是为了表明有很多方法可以给猫皮肤涂抹:
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();
答案 3 :(得分:0)
如果你改变了怎么办?
select el.Element("Room");
到
select el.Elements("Room");
答案 4 :(得分:0)
您只在中间查询中选择一个房间,它应该是.Elements(...)
(注意尾随s
):
var rooms = from el in sections
where el.Element("SectionId").Value.Equals("001001")
select el.Elements("Room");
这同样适用于您的section
查询。