2015-12-21 8 views
1

Мне нужно разбить XML на файлы. Это структура моего образца XML:Разделить xml в файлы - метод занимает меньше памяти

<Data Code="L6POS1"> 
<Lots RowVersion="464775"> 
    <Lot Id="5" Quantity="10068.0000" GUID="AA616D3D-F442-6AEE-0BAB-1D13F6961C2A" /> 
    <Lot Id="99" Quantity="0.0000" GUID="24A9C957-EC98-85D5-8F96-0120F6E8A572" /> 
    <Lot Id="101" Quantity="0.0000" GUID="124D17A2-1568-DB02-4327-4669FE00F741" /> 
    <Lot Id="103" Quantity="0.0000" GUID="DD1730FF-27CF-1269-7AC2-3152CB6FDC46" /> 
    <Lot Id="105" Quantity="0.0000" GUID="1F25378F-30D4-E4E0-9939-1E9E69C806C1" /> 
    <Lot Id="188" Quantity="0.0000" GUID="2E860029-29B3-54C2-B8D1-0C6ABDA42DFF" /> 
    <Lot Id="189" Quantity="0.0000" GUID="D3C58850-BC23-E8DE-A919-09CCB3F8A1D3" /> 
</Lots> 

Ожидаемый результат: FirstFile:

<Data Code="L6POS1"> 
<Lots RowVersion="464775"> 
    <Lot Id="5" Quantity="10068.0000" GUID="AA616D3D-F442-6AEE-0BAB-1D13F6961C2A" /> 
    <Lot Id="99" Quantity="0.0000" GUID="24A9C957-EC98-85D5-8F96-0120F6E8A572" /> 
    <Lot Id="101" Quantity="0.0000" GUID="124D17A2-1568-DB02-4327-4669FE00F741" /> 
    <Lot Id="103" Quantity="0.0000" GUID="DD1730FF-27CF-1269-7AC2-3152CB6FDC46" /> 
</Lots> 
</Data> 

SecondFile И:

<Data Code="L6POS1"> 
<Lots RowVersion="464775"> 
    <Lot Id="105" Quantity="0.0000" GUID="1F25378F-30D4-E4E0-9939-1E9E69C806C1" /> 
    <Lot Id="188" Quantity="0.0000" GUID="2E860029-29B3-54C2-B8D1-0C6ABDA42DFF" /> 
    <Lot Id="189" Quantity="0.0000" GUID="D3C58850-BC23-E8DE-A919-09CCB3F8A1D3" /> 
</Lots> 
</Data> 

На самом деле я использую:

private IEnumerable<XElement> CreateXMLPackagesByType(string syncEntityName, XElement root) 
    { 
     var xmlList = new List<XElement>(); 
     IEnumerable<XElement> childNodes = root.Elements(); 

     var childsCount = childNodes.Count(); 

     var skip = 0; 
     var take = ConfigurationService.MaxImportPackageSize; 
     var rootAttributes = root.Attributes(); 
     XElement rootWithoutDescendants; 
     while (skip < childsCount) 
     { 
      rootWithoutDescendants = new XElement(root.Name); 
      rootWithoutDescendants.Add(rootAttributes); 

      var elems = childNodes.Skip(skip).Take(take); 
      skip += take; 
      xmlList.Add(CreatePackage(rootWithoutDescendants, elems)); 
     } 

     return xmlList; 
    } 


     private XElement CreatePackage(XElement type, IEnumerable<XElement> elems) 
    { 
     type.Add(elems); 
     var root = new XElement("Data", type); 
     root.Add(new XAttribute("Code", ConfigurationService.Code)); 
     return root; 
    } 

К сожалению, таким образом получите OutOfMemoryException с более крупными XML файлами на старом оборудовании. Это лучший способ разделить XElement?

+2

Рассмотрите [XmlReader] (https://msdn.microsoft.com/en-us/library/system.xml.xmlreader (v = vs.110) .aspx) вместо [LINQ to XML] (https://msdn.microsoft.com/en-us/library/system.xml.linq(v=vs.110).aspx)? –

+1

Вам необходимо использовать анализатор SAX, а не парсер документов. Как отмечает @Tom, XmlReader - хороший вариант. Вы также можете скомпилировать его для 64-битного - не лучшее решение - просто говоря :-) – Jim

ответ

1

Предыдущие комментарии, предлагающие использовать синтаксический анализатор SAX, являются правильными - таким образом вы получаете каждое событие (элемент и т. Д.) По одному, и после этого вам не нужно ничего хранить.

Если вы абсолютно уверены, что ваши данные так же четко разбиты на строки, как ваш пример, быстрый и грязный метод состоял бы в том, чтобы даже не разобрать, а просто читать строку за раз. Обращайтесь с первыми двумя, затем разложите все остальное, как хотите, а затем обработайте последние два. Но будьте действительно уверены (другими словами, отметьте), что каждый элемент <Lot> занимает ровно одну физическую линию; как вы, наверное, уже знаете, нет причин, по которым имеют, чтобы быть таким образом в XML в целом.

 Смежные вопросы

  • Нет связанных вопросов^_^