2010-09-04 14 views
69

Rozważmy następujący xml:Jak korzystać z XPath z XElement lub LINQ?

<response> 
    <status_code>200</status_code> 
    <status_txt>OK</status_txt> 
    <data> 
    <url>http://bit.ly/b47LVi</url> 
    <hash>b47LVi</hash> 
    <global_hash>9EJa3m</global_hash> 
    <long_url>http://www.tumblr.com/docs/en/api#api_write</long_url> 
    <new_hash>0</new_hash> 
    </data> 
</response> 

szukam naprawdę krótkim sposób uzyskać tylko wartość elementu <hash>. Próbowałem:

var hash = xml.Element("hash").Value; 

Ale to nie działa. Czy jest możliwe dostarczenie zapytania XPath do XElement? Mogę to zrobić ze starszą System.Xml ram, robiąc coś takiego:

xml.Node("/response/data/hash").Value 

Czy istnieje coś takiego w obszarze nazw LINQ?


UPDATE:

Po monkeying wokół z tego kilka znalazłem sposób, aby zrobić to, co usiłuję zrobić:

var hash = xml.Descendants("hash").FirstOrDefault().Value; 

bym nadal być zainteresowani, aby zobaczyć, czy ktoś ma lepsze rozwiązanie?

+3

Nie używaj FirstOfDefault() w w tym przypadku, ponieważ jeśli "hash" nie zostanie znaleziony, otrzymasz wyjątek NullReferenceException. Zamiast tego użyj opcji First(), a otrzymasz bardziej opisowy wyjątek. – kaalus

+2

Użyj First(), jeśli spodziewasz się, że "hash" zawsze istnieje. W przeciwnym razie FirstOrDefault() jest w porządku, o ile sprawdzisz wartość null przed uzyskaniem dostępu do właściwości Value. –

Odpowiedz

120

Aby użyć XPath z LINQ do XML dodaj deklarację użycia dla System.Xml.XPath, spowoduje to rozszerzenie zakresu o System.Xml.XPath.Extensions.

W przykładzie:

var value = (string)xml.XPathEvaluate("/response/data/hash"); 
+1

OK, wydaje się najbliżej oryginalnego pytania –

+3

Właściwie to (teraz?) W 'System.Xml.XPath'. –

+0

@DanFriedman to się nie poruszyło. Uwaga link jest do klasy docs, nieco wcześniej podaję przestrzeń nazw (bez linku). – Richard

13

Zobacz, kiedy do czynienia z LINQ do XML, dlaczego nie używaj LINQ, aby uzyskać rzeczywisty obiekt.

Potomkowie znajdują każdy element z całego kodu XML i wyświetlają wszystkie obiekty pasujące do podanej nazwy. W twoim przypadku hash to imię, które znajduje.

Więc zamiast robić

var hash = xml.Descendants("hash").FirstOrDefault().Value; 

bym rozpadają jak:

var elements = xml.Descendants("hash"); 
var hash = elements.FirstOrDefault(); 

if(hash != null) 
hash.Value // as hash can be null when default. 

W ten sposób można również uzyskać atrybuty węzłów elementów itd

sprawdzić ten artykuł do zorientuj się, jak to pomaga. http://www.codeproject.com/KB/linq/LINQtoXML.aspx Mam nadzieję, że to ci pomoże.

+2

@adhishek +1 dla wyjaśnienia wartości oddzielenia elementu od jego własnej zmiennej, dzięki czemu możesz robić inne rzeczy, takie jak atrybuty, itd. –

+1

Jednym z powodów używania XPath jest utrata tych wszystkich rzeczy, które XPath może zrobić i Linq nie może . Pierwszym oczywistym, który przychodzi na myśl, jest wykonanie zapytania, które jest zdefiniowane w środowisku wykonawczym (powiedzmy wyrażenie odczytane z konfiguracji lub cokolwiek innego). –

33

Inni całkiem rozsądnie sugerowali, jak użyć "natywnego" LINQ do zapytań XML, aby zrobić to, co chcesz.

Jednak w trosce o zapewnienie wiele alternatyw, należy rozważyć XPathSelectElement, XPathSelectElements i XPathEvaluate ocenić wyrażeń XPath przeciwko XNode (są wszystkie metody rozszerzenie na XNode). Możesz również użyć CreateNavigator, aby utworzyć XPathNavigator dla XNode.

Osobiście jestem wielkim fanem bezpośredniego używania LINQ do XML API, ponieważ jestem wielkim fanem LINQ, ale jeśli czujesz się bardziej komfortowo z XPath, powyższe może ci pomóc.

5

Można użyć metody .Element() do łańcucha elementy, tworząc strukturę podobną XPath.

Dla przykładu:

XElement xml = XElement.Parse(@"...your xml..."); 
XElement hash = xml.Element("data").Element("hash"); 
+0

Myślę, że jest to najlepsza odpowiedź, ponieważ wykonuje ona pracę, kontynuując używanie LINQ do XML (co jest zalecane) zamiast używać XPath z zapytaniem LINQ do XML (co nie jest zalecane). –

+1

Korzystanie z XPath jest bardziej zwięzłe, szczególnie jeśli szukasz wspaniałych dzieci lub nie tylko. –

1

Próbowałem wymyślić ramach LINQesq generowania XPath. Pozwala opisać XPath przy użyciu C# lambda wyrażenia

var xpath = CreateXpath.Where(e => e.TargetElementName == "td" && e.Parent.Name == "tr"); 

var xpath = CreateXpath.Where(e => e.TargetElementName == "td").Select(e => e.Text); 

Nie wiem, czy to jest pomocne w tym kontekście, ale można znaleźć dokumentację tutaj:

http://www.syntaxsuccess.com/viewarticle/how-to-create-xpath-using-linq

Powiązane problemy