问题
I am a C# programmer, so I don't get to take advantage of the cool XML syntax in VB.
Dim itemList1 = From item In rss.<rss>.<channel>.<item> _
Where item.<description>.Value.Contains("LINQ") Or _
item.<title>.Value.Contains("LINQ")
Using C#, I find XPath to be easier to think about, easier to code, easier to understand, than performing a multi-nested select using LINQ to XML. Look at this syntax, it looks like Greek swearing:
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
};
All the casting, the heavy syntax, the possibility for NullPointerExceptions. None of this happens with XPath.
I like LINQ in general, and I use it on object collections and databases, but my first go-round with querying XML led me right back to XPath.
Is it just me?
Am I missing something?
EDIT: someone voted to close this as "not a real question". But it is a real question, stated clearly. The question is: Am I misunderstanding something with LINQ to XML?
回答1:
Use what you feel the most comfortable with, as long as it gets the job done. I use both methods depending on what I need to do to with XML. It sounds to me like you've got a good handle on what LINQ is good for and what XPath is good for.
回答2:
Yes, the example you've given is unweildy.
But with LINQ comes the flexibility to refactor away the unweildiness.
Here's an example of how I would improve it. (This is done without any testing at all, and I don't even know the real class names, but it should convey the idea)
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")
};
回答3:
I'm guessing at some of your data types, but you could make your C# LINQ query concise by casting your attribute values:
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")
};
And I'm sure you already know the @ syntax you can use for attributes in VB's XML literals.
回答4:
I can see your problem but I used LINQ for just reorder a GPX file to get trackpoints in every segment in the correct order and it feels rather straight forward.....
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);
}
and also fix a bug in a delivered GPX file for time
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;
}
I think it is rather straight format....
(The problem I fixed http://www.everytrail.com/forum/viewtopic.php?f=4&t=1980&p=6447#p6447)
来源:https://stackoverflow.com/questions/1442585/is-it-just-me-i-find-linq-to-xml-to-be-sort-of-cumbersome-compared-to-xpath