2010-02-12 11 views

Odpowiedz

8

Tak, można połączyć XmlReader z method XNode.ReadFrom, zobacz przykład w dokumentacji, która używa języka C# do selektywnego przetwarzania węzłów znalezionych przez XmlReader jako XElement.

+0

genialny. Zajmuję się tworzeniem aplikacji, która będzie przetwarzać wiele plików XML 200M i XDocument mnie zabija. to zrobiło ogromną poprawę. dzięki. –

+4

Myślę, że jest błąd w przykładowym kodzie na stronie dokumentacji 'XNode.ReadFrom'. Wyrażenie "XElement el = XElement.ReadFrom (czytnik) jako XElement;" powinno być "XElement el = new XElement (reader.Name, reader.Value);' zamiast. Tak jak jest, pierwszy z dwóch elementów "Dziecko" jest pomijany w pliku XML, z którego czyta. –

+0

Mój ostatni komentarz również nie jest poprawny; pracuję nad tym teraz dla siebie ... –

0

Pamiętaj, że będziesz musiał czytać plik sekwencyjnie, a odnosząc się do rodzeństwa lub potomka będzie w najlepszym razie powolny, a w najgorszym - niemożliwe. W przeciwnym razie @MartinHonnn ma klucz.

+0

Ta odpowiedź powinna zostać usunięta i dodana jako komentarz. –

5

Przykładowy kod w dokumentacji MSDN dla metody XNode.ReadFrom jest następujący:

class Program 
{ 
    static IEnumerable<XElement> StreamRootChildDoc(string uri) 
    { 
     using (XmlReader reader = XmlReader.Create(uri)) 
     { 
      reader.MoveToContent(); 
      // Parse the file and display each of the nodes. 
      while (reader.Read()) 
      { 
       switch (reader.NodeType) 
       { 
        case XmlNodeType.Element: 
         if (reader.Name == "Child") 
         { 
          XElement el = XElement.ReadFrom(reader) as XElement; 
          if (el != null) 
           yield return el; 
         } 
         break; 
       } 
      } 
     } 
    } 

    static void Main(string[] args) 
    { 
     IEnumerable<string> grandChildData = 
      from el in StreamRootChildDoc("Source.xml") 
      where (int)el.Attribute("Key") > 1 
      select (string)el.Element("GrandChild"); 

     foreach (string str in grandChildData) 
      Console.WriteLine(str); 
    } 
} 

Ale odkryłem, że metoda w przykładzie StreamRootChildDoc musi zostać zmieniony w następujący sposób:

static IEnumerable<XElement> StreamRootChildDoc(string uri) 
    { 
     using (XmlReader reader = XmlReader.Create(uri)) 
     { 
      reader.MoveToContent(); 
      // Parse the file and display each of the nodes. 
      while (!reader.EOF) 
      { 
       if (reader.NodeType == XmlNodeType.Element && reader.Name == "Child") 
       { 
        XElement el = XElement.ReadFrom(reader) as XElement; 
        if (el != null) 
         yield return el; 
       } 
       else 
       { 
        reader.Read(); 
       } 
      } 
     } 
    }