2009-08-07 3 views
8

Mam dokument xml z elementem głównym, dwoma elementami podrzędnymi, "diagnostycznymi" i "wynikami". Element "results" ma wtedy dowolną liczbę elementów o nazwie "result"C# XmlDocument SelectNodes

Po załadowaniu do XmlDocument łatwo jest nawigować po strukturze i zobaczyć, jak dokładnie działa. Potrafię napisać funkcję rekursywną, która wybiera wszystkie elementy "wyniku". XmlDocument.SelectNodes ("// wyniki") znajduje węzeł bez problemu.

Jednak * XmlDocument.SelectNodes ("// wyniki/wynik") nic nie znajdzie.
* XmlDocument.SelectNodes ("// result") nie znajduje nic.

Rozmawiałem ze współpracownikiem i miał żal używając Xpath w XmlDocument.SelectNodes. Ktoś jeszcze ma taki problem? Jakieś rozwiązania?

XML FILE:

<?xml version="1.0" encoding="UTF-8"?> 
<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" yahoo:count="10" yahoo:created="2009-08-07T10:19:59Z" yahoo:lang="en-US" yahoo:updated="2009-08-07T10:19:59Z" yahoo:uri="http://query.yahooapis.com/v1/yql?q=select+*+from+search.news+where+query%3D%22Tanzania%22"> 
    <diagnostics> 
     <publiclyCallable>true</publiclyCallable> 
     <url execution-time="47"><![CDATA[http://boss.yahooapis.com/ysearch/news/v1/Tanzania?format=xml&start=0&count=10]]></url> 
     <user-time>49</user-time> 
     <service-time>47</service-time> 
     <build-version>2579</build-version> 
    </diagnostics> 
    <results> 
     <result xmlns="http://www.inktomi.com/"> 
      <abstract>Kakungulu Cup winners SC Villa face Tanzania’s Simba SC this afternoon at the National stadium in Dar es salaam. “We had a very tiresome journey. The road was so bad and the road blocks were so many. However, we finally reached but the boys were so tired,” said Kato.</abstract> 
      <clickurl>http://lrd.yahooapis.com/_ylc=X3oDMTQ4cXAxcnRoBF9TAzIwMjMxNTI3MDIEYXBwaWQDb0pfTWdwbklrWW5CMWhTZnFUZEd5TkouTXNxZlNMQmkEY2xpZW50A2Jvc3MEc2VydmljZQNCT1NTBHNsawN0aXRsZQRzcmNwdmlkA21VVGlta2dlQXUzeEYuM0xGQkQzR1pUU1FIS0dORXA4cUk4QUJJX1U-/SIG=12vhpskdd/**http%3A//www.monitor.co.ug/artman/publish/sports/SC_Villa_face_Simba_in_Tanzania_89289.shtml</clickurl> 
      <date>2009/08/07</date> 
      <language>english</language> 
      <source>The Monitor</source> 
      <sourceurl>http://www.monitor.co.ug/</sourceurl> 
      <time>20:22:32</time> 
      <title>SC Villa face Simba in Tanzania</title> 
      <url>http://www.monitor.co.ug/artman/publish/sports/SC_Villa_face_Simba_in_Tanzania_89289.shtml</url> 
     </result> 

XPATH

doc.SelectNodes ("// wynik") produkuje żadnych trafień.

+0

Czy masz próbkę danego xml? Czy to możliwe, że twoje elementy "wyniku" znajdują się w innej przestrzeni nazw niż elementy "wyników"? Czy są jakieś kwalifikacyjne prefiksy na elementach? –

Odpowiedz

18

Rob i Odpowiedzi Marca idą prawdopodobnie w dobrym kierunku - XmlDocument + namespaces + XPath może być trochę uciążliwy.

Jeśli możesz używać .NET 3.5, sugeruję użycie LINQ do XML. Pozwoliłoby to naprawdę proste:

XDocument doc = XDocument.Load("foo.xml"); 
XNamespace ns = "bar"; 
var results = doc.Descendants(ns + "result"); 

foreach (var result in results) 
{ 
    ... 
} 

zasadzie LINQ do XML jest lepszy API w niemal każdym względem, z mojego doświadczenia :) (wierzę, istnieje kilka możliwości, że brakuje, ale jeśli masz dostęp do .NET 3.5 zdecydowanie warto przynajmniej spróbować.)

+0

Dzięki Jon, przeszedłem na LINQ i jest o wiele ładniej! :) – Daniel

+0

ten zrobił to dla mnie, ale to była część XNamespace, która była moim problemem. * nienawidzę * dawać Jonowi Skeetowi więcej punktów ... ale, ... długi ogon i wszystko. –

+3

@John: Jeśli to jakieś pocieszenie, twoja sprawa nie dała mi więcej powtórzeń. Dotarłem do rep-capa około 9 godzin temu. –

12

To brzmi dla mnie jak przestrzenie nazw są problemami; trzeba zazwyczaj do korzystania z pomocy w XmlNamespaceManager za to i użyć aliasu w zapytaniach, tj

doc.SelectNodes("//x:results/x:result", nsmgr); 

(gdzie x jest zdefiniowana w nsmgr jako alias do danej przestrzeni nazw)

+0

Dzięki Mark, to było dokładnie to. – Daniel