我正在使用LINQ从XML文件中查找对象。找到对象后,我想打印其细节,但我不确定如何使用我找到的对象。
这是我的代码:
var apartmentExist =
from apartment1 in apartmentXml.Descendants("Apartment")
where (apartment1.Attribute("street_name").Value == newApartment.StreetName) &&
(apartment1.Element("Huose_Num").Value == newApartment.HouseNum.ToString())
select apartment1.Value;
if (apartmentExist.Any() == false)
{
Console.WriteLine("Sorry, Apartment at {0} or at num {1}", newApartment.StreetName,
newApartment.HouseNum);
}
else
{
//print the details of apartment1
}
我的XML是:
<?xml version="1.0" encoding="utf-8"?>
<Apartments>
<Apartment street_name="sumsum">
<Huose_Num>13</Huose_Num>
<Num_Of_Rooms>4</Num_Of_Rooms>
<Price>10000</Price>
<Flags>
<Elevator>true</Elevator>
<Floor>1</Floor>
<parking_spot>true</parking_spot>
<balcony>true</balcony>
<penthouse>true</penthouse>
<status_sale>true</status_sale>
</Flags>
</Apartment>
</Apartments>
答案 0 :(得分:5)
您LINQ查询返回IEnumerable<XElement>
如果您希望它返回多个元素,您可以使用foreach
循环来打印元素,如果只有一个结果,您可以调用{{ 1}}获取.Single()
的扩展方法,而不是集合:
使用XElement
属性将XElement
转换为string
更安全,因为当元素不存在时,它不会抛出XElement.Value
。您还应该使用NullReferenceException
强制转换并比较数字而不是(int)XElement
,并将其与数字的字符串表示形式进行比较。
您不应使用XElement.Value
方法,而是使用Descendants
。它会使您的查询更快,因为只会处理需要搜索的元素。
您应该致电Elements
并检查结果是否为FirstOrDefault
,而不是使用null
,然后再拨打Any
来电。它会阻止您的查询执行两次。
而不是返回First
,apartment1.Value
,而不是返回string
本身。这将是apartment1
,您可以在以后必要时获取内容。
XElement
答案 1 :(得分:0)
您可以使用以下一个linq查询来执行此操作:
var apartment =
(from a in apartmentXml.Descendants("Apartment")
where (a.Attribute("street_name").Value == newApartment.StreetName) &&
(a.Element("Huose_Num").Value == newApartment.HouseNum.ToString())
select new {
street_name = a.Attribute("street_name").Value,
Huose_Num = a.Element("Huose_Num").Value,
Num_Of_Rooms = a.Element("Num_Of_Rooms").Value,
Price = a.Element("Price").Value,
Flags = (from f in a.Element("Flags")
select new {
Elevator = f.Element("Elevator").Value,
Floor = f.Element("Floor").Value,
parking_spot = f.Element("Floor").Value,
balcony = f.Element("balcony").Value,
penthouse = f.Element("penthouse").Value,
status_sale = f.Element("status_sale").Value
})
}).FirstOrDefault();
if(aparment == null)
{
Console.WriteLine("Sorry, Apartment at {0} or at num {1}", newApartment.StreetName,
newApartment.HouseNum);
}
else
{
Console.WriteLine(apartment.street_name);
Console.WriteLine(apartment.Huose_Num);
Console.WriteLine(apartment.Num_Of_Rooms);
Console.WriteLine(apartment.Price);
Console.WriteLine(apartment.street_name);
Console.WriteLine(apartment.Flags.Elevator);
Console.WriteLine(apartment.Flags.Floor);
Console.WriteLine(apartment.Flags.parking_spot);
Console.WriteLine(apartment.Flags.balcony);
Console.WriteLine(apartment.Flags.penthouse);
Console.WriteLine(apartment.Flags.status_sale);
}
答案 2 :(得分:0)
试试这个:
var xml = @"<?xml version=""1.0"" encoding=""utf-8""?>
<Apartments>
<Apartment street_name=""sumsum"">
<Huose_Num>13</Huose_Num>
<Num_Of_Rooms>4</Num_Of_Rooms>
<Price>10000</Price>
<Flags>
<Elevator>true</Elevator>
<Floor>1</Floor>
<parking_spot>true</parking_spot>
<balcony>true</balcony>
<penthouse>true</penthouse>
<status_sale>true</status_sale>
</Flags>
</Apartment>
</Apartments>
";
var apartmentXml = XElement.Parse( xml );
//apartmentXml.Dump(); // This is a linqpad feature
var new_street = "sumsum";
var new_house_num = "13";
var match_apartment = apartmentXml.Elements().Where (x => x.Attribute("street_name").Value == new_street && x.Element("Huose_Num").Value == new_house_num );
//match_apartment.Dump();
if (match_apartment.Count() < 1 )
{
Console.WriteLine("Sorry, Apartment at {0} or at num {1}", new_street,
new_house_num);
}
else
{
foreach( var x in match_apartment.Elements() )
{
Console.WriteLine("{0} | {1}", x.Name, x.Value );
}
}
答案 3 :(得分:-2)
appatmentExist是一个IEnumerable,因此访问其中的各个项目使用List indexing来访问单个元素
Comsole.Writeline(appartmentExist.toList()[0].StreetName);
将打印上面查询中找到的第一个元素的街道名称