2010-02-12 13 views

risposta

8

Sì, è possibile combinare XmlReader con method XNode.ReadFrom, vedere l'esempio nella documentazione che utilizza C# per elaborare in modo selettivo i nodi trovati da XmlReader come XElement.

+0

brillante. sto sviluppando un'applicazione che elaborerà più file XML da 200 milioni e XDocument mi stava uccidendo. questo ha fatto un enorme miglioramento. Grazie. –

+4

Penso che ci sia un bug nel codice di esempio sulla pagina di documentazione 'XNode.ReadFrom'. L'istruzione 'XElement el = XElement.ReadFrom (reader) as XElement;' dovrebbe essere 'XElement el = new XElement (reader.Name, reader.Value);' invece. Così com'è, il primo di ogni due elementi "Figlio" viene saltato nel file XML dal quale viene letto. –

+0

Anche il mio ultimo commento non è del tutto corretto; lavorando su questo ora per me ... –

0

Ricorda che dovrai leggere il file in modo sequenziale e fare riferimento ai fratelli o discendenti sarà nel migliore dei casi lento e impossibile nel peggiore dei casi. Altrimenti @MartinHonnn ha la chiave.

+0

Questa risposta dovrebbe essere cancellata e aggiunta come commento. –

5

Il codice di esempio nella documentazione MSDN per il metodo XNode.ReadFrom è la seguente:

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); 
    } 
} 

Ma ho trovato che il metodo StreamRootChildDoc nell'esempio deve essere modificato come segue:

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(); 
       } 
      } 
     } 
    } 
Problemi correlati