2011-08-06 15 views
6
formacie XML

:Zaznacz węzły Linq do 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> 

Chcę wybrać wszystkie "LOC" węzły (element1, element2), ale to nie działa !!!

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

Odpowiedz

12

Podejrzewam problem jest to, że idziesz z document.Elements("url") zamiast document.Root.Elements("url") ... więc to szuka korzeniaurl elementu, który nie istnieje.

Spróbuj tego:

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

Zauważ, że nie użyłem Descendants tutaj, jak loc wszystkie elementy są bezpośrednio pod url elementów tak.

Inną alternatywą można użyć tylko wtedy, gdy loc elementy są właściwe w każdym razie, to tylko:

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

(Ja zakładając urlList wcześniej była pusta ... dla tego rodzaju sytuacji ja lubię używać LINQ dla całej operacji i eliminować pętle foreach, które właśnie dodają do kolekcji.)

EDYCJA: Kod działa dla mnie. Oto krótki, ale kompletny program:

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

Cześć Jon! Użyłem twojego kodu, ale mój URL nadal jest pusty! :((parsuję xml z ciągu) –

+0

@Chelsea_cole: Sprawdzam teraz ... –

+1

@Chelsea_cole: Działa dla mnie - opublikowałem kompletny program pokazujący, że działa. Zauważ, że musiałem naprawić twój oryginalny kod XML, od '' na końcu do ''. Proszę wypróbować mój kod, a następnie zobaczyć, jaka jest różnica między tym a tym, co próbowaliście ... –

1

Spróbuj tego:

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

To zwróci wartość "IEnumerable >", której nie uważam za pożądaną ... –

+0

@Jon Skeet Zaktualizowano odpowiedź. – VMAtm

+0

Sposób, w jaki działa 'Potomkowie()', nie ma potrzeby używania 'SelectMany' - istnieje przeciążenie, które * uruchamia * z' IEnumerable '. –