Friday, July 11, 2014

Поэлементное чтение больших xml-файлов

namespace Console4Fun
{
 using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Text;
 using System.Xml;
 using System.Xml.Linq;

 class XmlStreamElements
 {
  public static IEnumerable StreamElements(Stream xml,string elementName)
  {
   var settings = new XmlReaderSettings { NameTable = new NameTable() };
   var xmlns = new XmlNamespaceManager(settings.NameTable);
   var context = new XmlParserContext(null,xmlns,string.Empty,XmlSpace.Default,Encoding.UTF8);
   using (XmlReader reader = XmlReader.Create(xml,settings,context))
   {
    reader.MoveToContent();
    while (reader.Read())
     if (reader.NodeType == XmlNodeType.Element && reader.Name.Equals(elementName))
     {
      XElement element = null;
      try
      {
       element = XElement.ReadFrom(reader) as XElement;
      }
      catch 
      {
       yield break; 
      }
      yield return element;
     }
   }
  }

  /// Пример вызова
  static void Main()
  {
   using (var stream = File.OpenRead(@"c:\xml.xml"))
   {
    foreach (var feed in StreamElements(stream,"phone"))
    {
     foreach (var element in feed.Elements())
     {
      Console.WriteLine(element.Name + "\t" + element.Value);
      foreach (var attr in element.Attributes())
       Console.WriteLine("\t@" + attr.Name + "\t" + attr.Value);
     }
    }
   }
  }
 }
}

No comments: