2009-08-07 33 views
8

Tengo un documento xml con un elemento raíz, dos elementos secundarios, 'diagnóstico' y 'resultados'. El elemento 'resultados' tiene un número arbitrario de elementos con el nombre 'resultado'C# XmlDocument SelectNodes

Cuando esto se carga en un XmlDocument, es fácil navegar por la estructura y ver que así es exactamente como funcionan las cosas. Puedo escribir una función recursiva que selecciona todos los elementos de "resultado". XmlDocument.SelectNodes ("// results") encuentra un nodo sin problemas. Sin embargo, * XmlDocument.SelectNodes ("// resultados/resultado") no encuentra nada.
* XmlDocument.SelectNodes ("// result") no encuentra nada.

He hablado con un compañero de trabajo y ha tenido dolor usando Xpath en XmlDocument.SelectNodes. ¿Alguien más se encuentra con este tipo de problema? Alguna solución?

archivo XML:

<?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 ("número //") produce ningún golpe.

+0

¿Tienes una muestra del xml en cuestión? ¿Es posible que sus elementos de "resultado" estén realmente en un espacio de nombre diferente a los elementos de "resultados"? ¿Hay algún prefijo calificado en los elementos? –

Respuesta

18

Rob y Es probable que las respuestas de Marc vayan en la dirección correcta: XmlDocument + namespaces + XPath pueden ser un poco dolorosos.

Si puede usar .NET 3.5, le sugiero que utilice LINQ to XML en su lugar. Eso haría realmente fácil:

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

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

Básicamente LINQ to XML es un API superior en casi todos los sentidos, en mi experiencia :) (Creo que hay algunas capacidades que le falta, pero si usted tiene acceso a .NET 3.5 definitivamente vale la pena intentarlo al menos.)

+0

Gracias Jon, cambié a LINQ y es mucho más agradable. :) – Daniel

+0

este lo hizo por mí, pero fue la parte XNamespace que fue mi problema. * odio * darle a Jon Skeet más puntos ... pero, ... cola larga y todo. –

+3

@John: Si te sirve de consuelo, tu voto no me dio más representantes. Llegué al límite de reputación hace aproximadamente 9 horas. –

12

Me parece que los espacios de nombres son los problemas; normalmente hay que contar con la ayuda de un XmlNamespaceManager para esto, y utilizar un alias en sus consultas, es decir

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

(donde x se define en nsmgr como un alias para el espacio de nombres dado)

+0

Gracias Mark, eso fue exactamente. – Daniel

Cuestiones relacionadas