Linq To Xml i błąd Could not find an implementation of the query pattern for source

Chyba już standardowo weekendy będą poświęcone na wieczorne prace z DesktopInfo. Testując różne elementy, które będą przydatne dla aplikacji trafiłem na Linq To Xml.

Do czego służy LinqToXml? Do prostego czytania XML-a. Możemy stosować składnię Linq i czytać w ten sposób pliki xml-owe. Ładnie i miło. Poniżej przykład:

FileInfo inputXml = new FileInfo(@"d:\ExampleInput.xml");
            
XDocument xmlDoc = XDocument.Load(inputXml.OpenRead());

var selectedItems = from gadget in xmlDoc.Descendants("Gadget")
                    where gadget.Attribute("type").Value == "Location and maps"
                    select new GadgetInfo(){
                        Author = gadget.Attribute("author").Value,
                        Type = gadget.Attribute("type").Value,
                        Version = gadget.Attribute("version").Value,
                        Description = gadget.Value
                    };

 

Czyż nie jest to ładne? Zamiast (o zgrozo) ręcznie parsować plik lub uczyć się XPath-a można zaprzęgnąć Linq.

Problem jaki przy tym wyszedł to taki paskudny komunikat:

Could not find an implementation of the query pattern for source type 'System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>’. 'Where’ not found. Are you missing a reference to 'System.Core.dll’ or a using directive for 'System.Linq’?    

Rozwiązanie jest proste i banalne (i nawet w samym komunikacie błędu opisane) ale warto wspomnieć:

Aby pozbyć się tego błędu wystarczy dodać linijkę:

using System.Linq;

 

 

A jeśli chodzi o samo linqToXml to można dużo więcej niż tutaj pokazałem. Między innymi można tworzyć dokumenty xml. Co jeszcze ważniejsze, dzięki LinqToXml (i takiemu samemu kodowi) możemy korzystać z plików XML-owych w Silverlight 4 (czy we wcześniejszych też, nie wiem).

Powyższe zapytanie można by zapisać przy pomocy XPath w ten sposób:

FileInfo inputXml = new FileInfo(@"d:\ExampleInput.xml");
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(inputXml.OpenRead());

var selectedItems = xmlDoc.SelectNodes(@"/Gadgets/Gadget[@type=""Location and maps""]");

 

Czyli trochę krócej, jednak po pierwsze trzeba znać składnię XPath-a (która nie jest trudna ale tak samo jak RegEX-y nieużywana szybko się ulatnia 🙂 ) ale selectedItems tym razem zawierają XmlNodeList z których jakoś musimy zrobić obiekty. Czy ktoś ma jeszcze jakieś pomysły? Jak można szybko i łatwo wyciągnąć dane z pliku xml? Może coś na s… ???