2009-09-18 7 views
7

Sono un programmatore C#, quindi non posso sfruttare la sintassi XML di VB.Sono solo io? Trovo che LINQ to XML sia un po 'macchinoso, rispetto a XPath

Dim itemList1 = From item In rss.<rss>.<channel>.<item> _ 
       Where item.<description>.Value.Contains("LINQ") Or _ 
         item.<title>.Value.Contains("LINQ") 

con C#, trovo XPath essere più facile da pensare, più facile da codice, più facile da capire, che l'esecuzione di un multi-SELECT nidificato utilizzando LINQ to XML. Guardate questa sintassi, sembra giuramento greca:

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 
      }; 

Tutto il casting, la sintassi pesante, la possibilità per NullPointerExceptions. Niente di tutto questo accade con XPath.

Mi piace LINQ in generale, e lo utilizzo su raccolte di oggetti e database, ma il mio primo go-round con query XML mi ha portato direttamente a XPath.

Sono solo io?

Mi manca qualcosa?


EDIT: qualcuno ha votato per chiudere questa come "non una vera e propria domanda". Ma è è una vera domanda, dichiarata chiaramente. La domanda è: Sto fraintendendo lo con LINQ to XML?

+2

Sì, sei proprio tu.: p –

+2

Sono d'accordo, adoro L2O, L2S ecc. ma quando si ha a che fare con xml mi limito ad usare xpath insieme a xmldocument/xmlnode/xmlelement ecc. Linq-to-XML è forse più facile da usare ma se si ha xpath tra le dita quindi non batterà xpath ... – KristoferA

+3

No, non sei solo tu. Linq-to-XML potrebbe sembrare un approccio "più intelligente", ma come te, preferisco ancora XPath. Se conosci XPath e puoi farne uso - con tutti i mezzi, fallo! :-) Non sei solo :-) –

risposta

4

Utilizzare ciò che si sente più a suo agio, purché il lavoro sia svolto. Io uso entrambi i metodi a seconda di cosa devo fare con XML. Mi sembra che tu abbia una buona padronanza su ciò per cui LINQ è buono e su ciò che XPath fa bene.

5

Sì, l'esempio che hai fornito non è soddisfacente.

Ma con LINQ arriva la flessibilità di refactoring via la spiacevolezza.

Ecco un esempio di come migliorerei. (Questo è fatto senza alcun test a tutti, e io non so nemmeno i nomi reali di classe, ma deve trasmettere l'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")   
       }; 
+0

È ancora molto più macchinoso di un'elegante espressione XPath. –

+0

@DimitreNovatchev Mi piacerebbe vedere la tua elegante espressione xpath che restituisce la raccolta di cui sopra. –

+0

@TimJarvis: Vorrei specificarne uno: potresti specificare il documento XML e quali nodi esattamente dovrebbero essere selezionati? Questi non sono forniti nella risposta di cui sopra, che lo rendono ancora più sospeso nell'aria. –

1

Sto indovinando ad alcuni dei vostri tipi di dati, ma si potrebbe rendere il vostro C# query LINQ concisa lanciando i valori degli attributi:

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") 
    }; 

E sono sicuro che si conosce già la sintassi @ è possibile utilizzare per gli attributi in XML letterali di VB.

+0

È ancora molto più ingombrante di un'elegante espressione XPath –

+0

È da un po 'che non mi occupo di XPath diretto (e non lo uso con Linq in Xml), ma un esempio dell'espressione XPath "più semplice" sarebbe ottimo . Personalmente, penso che questo esempio sia eccellente, ed è il modo in cui normalmente faccio le cose. –

+0

@ Ryan-Versaw Mi piacerebbe fornire un'espressione XPath (sia XPath 1.0 o XPath 2.0), se è disponibile un documento XML specifico e se esiste una descrizione rigorosa di quale risultato deve essere prodotto. –

1

posso vedere il tuo problema ma ho usato LINQ solo per riordinare un file GPX per ottenere punti di traccia in ogni segmento nell'ordine corretto e ci si sente piuttosto semplice .....

 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); 
     } 

e anche correggere un bug in un file GPX consegnato per tempo

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; 
    } 

Penso che sia formato piuttosto dritto ....

(Il problema che ho risolto http://www.everytrail.com/forum/viewtopic.php?f=4&t=1980&p=6447#p6447)