现在,我想在XML文件中获取一些特定信息。以下是我对XML的看法:
<?xml version="1.0" encoding="utf-8" ?>
<root>
<world>
<region name="TestRegion">
<area name="TestArea">
<building name="Outside">
<room name="TutorialRoom">
<stuffToTake>All the text I want to take</stuffToTake>
</room>
</building>
</area>
</region>
</world>
</root>
我在线查看了如何使用代码执行此操作,并且我看到了此实现。我刚刚将它改编为我的代码:
XElement xelement = XElement.Load("..\\..\\LocationDatabase.xml");
var TextToDisplay = from regions in xelement.Elements("world")
where (string)regions.Element("region").Attribute("name") == "TestRegion"
where (string)regions.Element("region").Element("area").Attribute("name") == "TestArea"
where (string)regions.Element("region").Element("area").Element("building").Attribute("name") == "Outside"
where (string)regions.Element("region").Element("area").Element("building").Element("room").Attribute("name") == "TutorialRoom"
select regions;
foreach (var xEle in TextToDisplay)
{
Console.WriteLine(xEle.Element("region").Element("area").Element("building").Element("room").Element("stuffToTake").Value);
}
到目前为止,这很好用。
这里的问题是我在XML上面添加了一些数据
<?xml version="1.0" encoding="utf-8" ?>
<root>
<world>
<region name="LolNope">
<area name="TestArea">
<building name="Outside">
<room name="TutorialRoom">
<stuffToTake>All the text I want to take</stuffToTake>
</room>
</building>
</area>
</region>
<region name="TestRegion">
<area name="TestArea">
<building name="Outside">
<room name="TutorialRoom">
<stuffToTake>All the text I want to take</stuffToTake>
</room>
</building>
</area>
</region>
</world>
</root>
然后,它只是变成一个空的控制台窗口:
这究竟是什么问题?我假设它检查第一个区域是否有名称TestRegion,但是因为它没有失败并且停止检查其余区域。
答案 0 :(得分:1)
您需要做的是将您的查询链接到linq-to-xml,一次选择每组元素。
// all worlds
var worlds = xelement.Elements("world");
// all regions in the worlds where the attribute "name" is "TestRegion"
var regions = worlds.Elements("region")
.Where (region => (string)region.Attribute("name") == "TestRegion");
// all areas in the specified regions where the attribute "name" is "TestArea"
var areas = regions.Elements("area")
.Where (area => (string)area.Attribute("name") == "TestArea");
// all buildings in the specified areas where the attribute "name" is "Outside"
var buildings = areas.Elements("building")
.Where (building => (string)building.Attribute("name") == "Outside");
// all rooms in the specified buildings where the attribute "name" is "TutorialRoom"
var rooms = buildings.Elements("room")
.Where (room => (string)room.Attribute("name") == "TutorialRoom");
// all stuff to take in the specified rooms
var stuffs = rooms.Elements("stuffToTake");
// all the contents of the stuffs as an enumerable (there might be more than one, after all)
var values = stuffs.Select (stuff => stuff.Value);
foreach (var value in values)
{
Console.WriteLine(value);
}
而且,没有中间变量:
var values = xelement.Elements("world")
.Elements("region").Where (region => (string)region.Attribute("name") == "TestRegion")
.Elements("area").Where (area => (string)area.Attribute("name") == "TestArea")
.Elements("building").Where (building => (string)building.Attribute("name") == "Outside")
.Elements("room").Where (room => (string)room.Attribute("name") == "TutorialRoom")
.Elements("stuffToTake")
.Select(stuff => stuff.Value);
答案 1 :(得分:1)
你可以这样做,如果你想深入了解东西ToTake:
var result = root.Elements("world")
.Elements("region")
.Where (r => r.Attribute("name").Value == "TestRegion")
.Elements("area")
.Elements("building")
.Elements("room")
.Elements("stuffToTake")
.Select (r => r.Value);
result.Dump();
如果要在更深层次上过滤区域或建筑物或房间,只需在选择元素后应用where子句,然后按属性过滤:
.Elements("region")
.Where (r => r.Attribute("name").Value == "TestRegion")
.Elements("area")
.Where(ar => ar.Attribute("name").Value == "TestArea")
.Elements("building")
.Where(bui => bui.Attribute("name").Value == "Outside")
.Elements("room")
我倾向于将所有方法都放在前面的方法之下,但如果这更适合您的阅读和理解,您也可以将Where()
方法直接置于Element -selection之后:
.Elements("region").Where (r => r.Attribute("name").Value == "TestRegion")
.Elements("area").Where(ar => ar.Attribute("name").Value == "TestArea")
.Elements("building").Where(bui => bui.Attribute("name").Value == "Outside")
.Elements("room")...
重要的部分是按属性名称进行过滤。亲自尝试一下: http://share.linqpad.net/vns5le.linq