2010-01-06 25 views
1

我對XSLT非常陌生,我需要做的第一件事就是解析一個300MB的文件(這在小端)。 XSLT目前並不複雜,它只是刪除一些符合特定條件的節點。 我有兩個問題:XslCompiledTransform是否應歸咎於大型文件的慢速XML轉換?

  1. 它太慢了。處理500,000條記錄需要50秒,但速度不夠快。
  2. 它消耗500MB的內存,所以這隻會在文件變大時變得更糟。

有沒有什麼我可以在.net本地做的是使表現更好?

我知道我可以看看基於SAX的解析,或STX(在another post中提到),但我寧願留在.net邊界內。

謝謝!

編輯: 這裏是我的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:test="http://schemas...."> 
<xsl:output omit-xml-declaration="yes"/> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
</xsl:template> 
<xsl:template match="test:QueryRow[test:Columns/test:QueryColumn[test:Name='hit_count' and test:Value>200]]"/> 
</xsl:stylesheet> 

這裏是我用來做代碼轉換

XslCompiledTransform compiledTransform = new XslCompiledTransform(); 
XsltSettings settings = new XsltSettings(); 
settings.EnableScript = true; 
XmlReader xmlReader = XmlReader.Create("in.xml"); 
XmlWriter xmlWriter = XmlWriter.Create("out.xml"); 
compiledTransform.Load("format.xslt", settings, null); 
compiledTransform.Transform(xmlReader, xmlWriter); //this is what takes a long time 

此刻我想剛纔讀的文件,並將其寫回但它似乎實際上是將整個文件讀入內存,所以我試圖找到一種逐行讀取它的方法。

+0

你可以發佈你的XSLT嗎? – 2010-01-07 01:33:49

+0

另外,發佈您用於調用轉換的代碼。還要突出顯示需要50秒的代碼行。 – 2010-01-07 01:37:07

+0

需要多長時間*)讀取源文件和*)使用*)File.ReadAllBytes/WriteAllBytes和*)file.ReadAllText/WriteAllText編寫文件的副本,以及什麼執行時間會「足夠快」? – devio 2010-01-07 01:58:09

回答

2

您正在過濾的XPath表達式沒有任何明顯的錯誤,因此如此。但很容易想象它是一個問題。如果您的所有元素都有20 Column個孩子,其中每個孩子都有20個孩子,那麼XSLT處理器在決定給定的元素不匹配之前必須檢查400個元素。這可想而知非常低效,因爲如果事實證明該元素不應被過濾,則XSLT處理器必須再次訪問所有400個元素才能將其全部輸出。

The。NET實現類似SAX的XML解析的方法是子類XmlReader,在這種情況下,您可以想到它的作用:基本上,構建一個XmlReader緩衝QueryRow元素,因爲它讀取它們的後代直到它確定它們正常,然後返回它們給Read方法的調用者。這將比使用XSLT過濾XML要快得多,因爲使用XmlReader並不要求您在過濾之前構建未過濾的XML文檔的內存中表示。

+0

這幾乎是我現在想要做的。緩衝每個查詢行,然後過濾它。 – PBG 2010-01-08 12:54:09

1

你可以試試看看Saxon,我聽說它是​​一個非常好的XSLT處理器。但是完整的XSLT不可能以流方式進行處理,即使您的轉換聽起來像是這樣,所以除非XSLT處理器非常擅長優化(據我所知,撒克遜是最好的之一,如果不是最好的),您的內存消耗問題可能無法解決。

3

嘗試分析您的XSLT。 oXygen has a nice profiling capability可以告訴你熱點在變換中的位置。

oXygen HotSpots

你可以有一些低效率的XPATH表達式(如// *),或具有埋藏邏輯的模板內(如大量的for-each,如果選擇等),即防止XSLT引擎優化。將某些邏輯移入模板匹配標準可以幫助引擎優化並減少迭代和評估的節點集的大小。