2011-08-06 15 views
6
formato de archivo XML

:seleccionar nodos LINQ to XML C#

<?xml version="1.0" encoding="UTF-8"?> 
    <urlset>  
     <url> 
      <loc>element1</loc> 
      <changefreq>daily</changefreq> 
      <priority>0.2</priority> 
     </url> 
     <url> 
      <loc>element2</loc> 
      <changefreq>daily</changefreq> 
      <priority>0.2</priority> 
     </url> 
    <urlset> 

Quiero seleccionar todos los nodos "Loc" (element1, elemento2), pero esto no funciona !!!

foreach (XElement item in document.Elements("url").Descendants("loc")) // Change into what? 
{ 
     urlList.Add(item.Value); 
} 

Respuesta

12

Sospecho que el problema es que usted va a document.Elements("url") en lugar de document.Root.Elements("url") ... así que es la búsqueda de un elemento deraíz del url, que no existe.

Prueba esto:

List<string> urlList = doc.Root.Elements("url") 
           .Elements("loc") 
           .Select(x => (string) x) 
           .ToList(); 

Tenga en cuenta que no he utilizado Descendants aquí, ya que los elementos son todos loc directamente debajo url elementos de todos modos.

Otra alternativa podría utilizar si los sóloloc elementos son los más adecuados todos modos, es simplemente:

List<string> urlList = doc.Descendants("loc") 
          .Select(x => (string) x) 
          .ToList(); 

(Asumo urlList estaba vacío ... de antemano para este tipo de situación que desea utilizar LINQ para toda la operación y eliminar foreach bucles que acaban de agregar a una colección.)

EDITAR: El código funciona para mí. He aquí un programa corto pero completo:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Xml.Linq; 

class Test 
{ 
    static void Main(string[] args) 
    { 
     string xml = @"<?xml version=""1.0"" encoding=""UTF-8""?> 
    <urlset>  
     <url> 
      <loc>element1</loc> 
      <changefreq>daily</changefreq> 
      <priority>0.2</priority> 
     </url> 
     <url> 
      <loc>element2</loc> 
      <changefreq>daily</changefreq> 
      <priority>0.2</priority> 
     </url> 
    </urlset>"; 

     XDocument doc = XDocument.Parse(xml); 
     List<string> urlList = doc.Root 
            .Elements("url") 
            .Elements("loc") 
            .Select(x => (string) x) 
            .ToList(); 
     Console.WriteLine(urlList.Count); 
    } 
} 
+0

Hola Jon! ¡Utilicé tu código pero mi urlList todavía está vacío! :((analizo xml de una cadena). –

+0

@Chelsea_cole: Comprobando ahora ... –

+1

@Chelsea_cole: Funciona para mí - He publicado un programa completo que lo muestra funcionando. Tenga en cuenta que tuve que arreglar su XML original, de '' al final de ''. Por favor, prueba mi código, y luego mira cuál es la diferencia entre eso y lo que estabas intentando ... –

1

Prueba esto:

var query = for x in xDoc.Descendants("url") 
      select (string)x.Element("loc"); 

foreach (string loc in query) 
{ 
    urlList.Add(loc); 
} 
3
var xDoc = XDocument.Parse(
    @"<urlset>  
     <url> 
      <loc>element1</loc> 
      <changefreq>daily</changefreq> 
      <priority>0.2</priority> 
     </url> 
     <url> 
      <loc>element2</loc> 
      <changefreq>daily</changefreq> 
      <priority>0.2</priority> 
     </url> 
    </urlset>"); 
var locElements = xDoc.Descendants("url").SelectMany(el => el.Descendants("loc")); 
+0

Eso devolverá un 'IEnumerable >' que no creo que sea lo que se quería ... –

+0

@Jon Skeet Actualizado la respuesta. – VMAtm

+0

La forma en que 'Descendants()' funciona, no hay necesidad de usar 'SelectMany' - hay una sobrecarga que * comienza * con un' IEnumerable '. –