2013-09-24 108 views
2

我有要求生成一個XML文件。這在C#中很容易實現。問題(除了慢數據庫查詢[單獨問題])是輸出文件容易達到2GB。最重要的是,輸出XML的格式不是很容易在SQL中完成。每個父元素聚合子元素中的元素維護一個跨越文件的順序唯一標識符。 示例:非常大的XML文件生成

<level1Element> 
    <recordIdentifier>1</recordIdentifier> 
    <aggregateOfLevel2Children>11</aggregateOfL2Children> 
    <level2Children> 
     <level2Element> 
     <recordIdentifier>2</recordIdentifier> 
      <aggregateOfLevel3Children>92929</aggregateOfLevel3Children> 
      <level3Children> 
       <level3Element> 
        <recordIdentifier>3</recordIdentifier> 
        <level3Data>a</level3Data> 
       </level3Element> 
       <level3Element> 
        <recordIdentifier>4</recordIdentifier> 
        <level3Data>b</level3Data> 
       </level3Element> 
      </level3Children> 
     </level2Element> 
     <level2Element> 
     <recordIdentifier>5</recordIdentifier> 
      <aggregateOfLevel3Children>92929</aggregateOfLevel3Children> 
      <level3Children> 
       <level3Element> 
        <recordIdentifier>6</recordIdentifier> 
        <level3Data>h</level3Data> 
       </level3Element> 
       <level3Element> 
        <recordIdentifier>7</recordIdentifier> 
        <level3Data>e</level3Data> 
       </level3Element> 
      </level3Children> 
     </level2Element> 
    </level2Children> 
</level1Element> 

正在使用的模式實際上升了五個級別。爲了簡潔起見,我只包括3個。我不控制這個模式,也不能請求對其進行更改。

在對象中聚合所有這些數據並根據此模式序列化爲XML是一件簡單的事,甚至是微不足道的事情。但是,在處理如此大量的數據時,使用此策略時會發生內存不足異常。

對我來說這個策略是這樣的:我通過ObjectContext填充實體的集合,在SQL Server數據庫中創建一個視圖(這是一個效率最低的索引數據庫)。我將這個集合分組,然後迭代,然後分組下一個層次,然後迭代,直到我到達最高級別的元素。然後,我將數據組織到反映模式的對象(實際上只是映射)並設置順序recordIdentifier(我曾考慮過在SQL中執行此操作,但嵌套連接或CTE的數量會很荒謬,因爲標識符跨越標題元素進入子元素)。我寫一個更高級別的元素(比如說level2Element)和它的孩子到輸出文件。一旦我完成了這個級別的編寫工作,我將轉到父組,並將頭部與聚合數據及其標識符一起插入。

有沒有人有更好的方式輸出這樣一個大的XML文件的想法?

+4

你想知道如何*輸出*它?如果您在合理的現代機器上使用['XMLTextWriter'](http://msdn.microsoft.com/zh-cn/library/system.xml.xmltextwriter.aspx),則文件大小應該僅受限於可用的硬盤空間量。 –

+0

請顯示你的嘗試。將XML輸出寫入文件有許多不同的方法。 –

+0

May [the post](http://stackoverflow.com/questions/16432916/best-approach-to-write-huge-sql-dataset-into-xml-file/16433436#16433436)可以幫助你。 –

回答

1

據我瞭解你的問題,你的問題不是有限的存儲空間,即HDD。你很難在內存中保留一個大的XDocument對象,即RAM。爲了處理這個問題,你可以忽略這樣一個巨大的對象。對於每個recovrdIdentifier元素,您可以撥打.ToString()並獲取一個字符串。現在,只需將這些字符串附加到一個文件中即可。把聲明和根標籤放在這個文件中,你就完成了。