我是一名C#程序员,所以我无法利用VB中的酷XML语法。
Dim itemList1 = From item In rss.<rss>.<channel>.<item> _
Where item.<description>.Value.Contains("LINQ") Or _
item.<title>.Value.Contains("LINQ")
使用C#,我发现XPath比使用LINQ to XML执行多嵌套选择更容易思考,更容易编码,更容易理解。看看这个语法,看起来像希腊语咒骂:
var waypoints = from waypoint in gpxDoc.Descendants(gpx + "wpt")
select new
{
Latitude = waypoint.Attribute("lat").Value,
Longitude = waypoint.Attribute("lon").Value,
Elevation = waypoint.Element(gpx + "ele") != null ?
waypoint.Element(gpx + "ele").Value : null,
Name = waypoint.Element(gpx + "name") != null ?
waypoint.Element(gpx + "name").Value : null,
Dt = waypoint.Element(gpx + "cmt") != null ?
waypoint.Element(gpx + "cmt").Value : null
};
所有强制转换,重语法,NullPointerExceptions的可能性。 XPath不会发生这种情况。
我一般都喜欢LINQ,而且我在对象集合和数据库上使用它,但是我第一次查询XML时又回到了XPath。
只是我吗?
我错过了什么吗?
编辑:有人投票决定将其视为“不是真正的问题”。但它是一个真实的问题,清楚地说明了。问题是:我误解了 使用LINQ to XML的东西?
答案 0 :(得分:5)
是的,你给出的例子是unweildy。
但是使用LINQ可以灵活地重构不合情理。
这是我如何改进它的一个例子。 (这完全没有任何测试,我甚至不知道真正的类名,但它应该传达这个想法)
static class LinqXmlExtension
{
public static NodeThingy ElementOrNull(this XmlElement ele, string searchString)
{
return (ele.Element(searchString) != null ? ele.Element(searchString).Value : null);
}
}
//
/////////////////////////////////////////////////////////////////
var waypoints = from waypoint in gpxDoc.Descendants(gpx + "wpt")
select new
{
Latitude = waypoint.Attribute("lat").Value,
Longitude = waypoint.Attribute("lon").Value,
Elevation = waypoint.ElementOrNull(gpx + "ele"),
Name = waypoint.ElementOrNull(gpx + "name"),
Dt = waypoint.ElementOrNull(gpx + "cmt")
};
答案 1 :(得分:4)
使用您感觉最舒服的东西,只要完成工作即可。我根据XML需要做什么来使用这两种方法。听起来对你来说,你已经很好地理解了LINQ的优点以及XPath的优点。
答案 2 :(得分:1)
我猜测你的某些数据类型,但你可以通过强制转换你的属性值来简化你的C#LINQ查询:
var waypoints =
from waypoint in gpxDoc.Descendants(gpx + "wpt")
select new
{
Latitude = (decimal)waypoint.Attribute("lat"),
Longitude = (decimal)waypoint.Attribute("lon"),
Elevation = (decimal?)waypoint.Element(gpx + "ele"),
Name = (string)waypoint.Element(gpx + "name"),
Dt = (DateTime?)waypoint.Element(gpx + "cmt")
};
我相信你已经知道可以用于VB的XML文字中的属性的@语法。
答案 3 :(得分:1)
我可以看到你的问题,但我使用LINQ只是重新排序一个GPX文件,以正确的顺序在每个段中获取跟踪点,感觉相当直接......
var trksegs = doc.Root.Descendants(ns + "trkseg");
foreach (var trkseg in trksegs)
{
List<XElement> trk = trkseg.Elements(ns + "trkpt")
.OrderBy(x => (string)x.Element(ns + "time")).ToList();
trkseg.RemoveAll();
trkseg.Add(trk);
}
并修复已交付的GPX文件中的错误
private static XDocument ConvertTimeElement(XDocument doc)
{
if (doc.Root != null)
{
var times = doc.Root.Descendants(ns + "time").ToList();
foreach (var time in times)
time.SetValue((string)ConvertSpotDateFormat(time));
}
return doc;
}
我认为这是相当直接的格式......
(我修复的问题http://www.everytrail.com/forum/viewtopic.php?f=4&t=1980&p=6447#p6447)