2014-02-12 84 views
1

我有一個相對較大的xml文件。即使我只需要文件的某些部分,客戶端也會發給我一個完整的文件。因此,我想解析出我需要的部分並處理這個新文件。如何複製xml文件的部分

這裏是XML

<Activity> 
    <RetailFormat>ABC</RetailFormat> 
    <FeedDate>2014-02-06 21:01:10</FeedDate> 
    <ActivityId>665507</ActivityId> 
    <ActivityTitle>ABC 3.9.14 Hawaii </ActivityTitle> 
    <StartDate>2014-03-09</StartDate> 
    <EndDate>2014-03-15</EndDate> 
    <StartTime>00:00:00</StartTime> 
    <EndTime>23:59:59</EndTime> 
    <JANumber>0</JANumber> 
    <PlanItemNo>0</PlanItemNo> 
    <ChannelType>Circular</ChannelType> 
    <Version> 
    </Version> 
</Activity> 

我有我需要尋找ActivityIDs的列表的一部分。如果ActivityID在列表中,我想將整個Activity複製到一個新文件中。如果沒有,我想轉到下一個活動。實際上是從開始標記開始向下數百行。除了手動解析部分之外,我還沒有使用過xml。我不知道是否有程序化的方式來處理這個問題。另外,我需要大概15K行文件。該文件中有130萬行。通過限制處理文件的大小,我可以大幅縮短處理時間。

我在尋找最有效的方法來解決這個問題。手動操作我很好,但我寧願儘早限制它。

+0

這裏有一個大'如果'但'如果'文件被格式化,即。每行一行,而不是一個巨大的無格式文本/ XML文件,那麼你可以把它看作是一個普通的文件,並使用流讀取器,直到你找到一條符合你要找的內容的行,這將節省內存併成爲非常快。選項二,linq-to-xml並遵循以下示例:http://msdn.microsoft.com/en-us/library/vstudio/bb387013(v=vs.100).aspx –

回答

1

如果文件非常大並且內存使用是一個問題,您應該使用SAX解析器(使用您選擇的語言 - 將其添加到您的標記中)。 SAX不適用於樹,因此在解析時必須自己重建子樹。其優點是不需要將整個XML加載到內存中。你只存儲你真正需要的東西。

SAX解析器是一個基於事件的XML解析器,它將按順序讀取您的文件並生成事件。事件的處理方法如startElement(...),startDocument(...),endElement(...),characters(...)等。您必須編寫一個處理程序來捕獲您希望實施這些方法的事件。

你的處理程序必須實現startElement()characters()endElement(),並用實例變量來保存相關數據,您將需要方法(例如之間:數組當前元素,來存儲你的代碼片段等

如果內存不是問題,則可以使用DOM或XSLT,使用DOM可以使用getElementsByTagName("Activity")來檢索<Activity>子樹的數組,然後在該子樹上使用DOM方法檢查<ActivityID>,然後可以複製所需的子樹,添加他們到另一個根目錄,或從當前根目錄中刪除那些你不想要的目錄。

使用XSLT,您可以編寫一個XML模板,用於選擇帶有XPath表達式的所有<Activity>節點,例如//Activity,將ID比較//Activity/ActivityID與ID列表進行比較,並生成僅包含Activity節點的結果樹。

通知您正在使用的語言,我可能會向您發送一些示例。

+0

我是編程語言不可知論者。我基本上會像其他一些人一樣學習這門語言。我的大問題是,當我完成過去的手動解析時,我已經將70兆文件減少到了5以下。有沒有一種語言適合這種類型的操作? –

+0

上述解決方案是您在Java或Ruby中使用SAX解析器解決問題的方式。Objective-C中的NSXMLParser也有類似的功能。我沒有在C#或LINQ中知道這樣的事情,但我並不是一個真正的.NET程序員,並且我很久沒有使用C#,所以我可能是錯的。您可以使用XmlReader以有效的內存方式讀取C#中的XML流。 XLinq使用像DOM這樣的對象模型,並且在處理之前必須加載完整的XML內容(據我所知,Linq to XML仍然如此)。 – helderdarocha

+0

我在Java中有一個例子,它使用兩個類(一個用於啓動解析器,另一個用於處理標記事件)基於具有與您相同結構的XML源文件中的子節點提取數據。我現在將它上傳到github並很快發佈鏈接。 – helderdarocha