2011-02-14 55 views
6

我遇到了約20-30 MB(650000行)的XML文件循環問題。在大型XML文件中循環播放

這是我的薈萃代碼:

<cffile action="READ" ile="file.xml" variable="usersRaw"> 

<cfset usersXML = XmlParse(usersRaw)> 
<cfset advsXML = XmlSearch(usersXML, "/advs/advuser")> 
<cfset users = XmlSearch(usersXML, "/advs/advuser/user")> 

<cfset numUsers = ArrayLen(users)> 
<cfloop index="i" from="1" to="#numUsers#"> 
    ... some selects... 
    ... insert... 
    <cfset advs = annunciXml[i]["vehicle"]> 
    <cfset numAdvs = ArrayLen(advs)> 
    <cfloop index="k" from="1" to="#numAdvs#">   
     ... insert... or ... update... 
    </cfloop> 
</cfloop> 

xml文件的結構是(是的,不太好:-)

<advs> 
    <advuser> 
     <user> 
     </user> 
     <vehicle> 
     <vehicle> 
    </advuser> 
</advs> 

後〜12萬行我得到一個錯誤:「內存不足」。

如何提高腳本的性能?

如何診斷哪裏存在最大內存消耗?

回答

10

@SamG是正確的,ColdFusion的XML解析不能做到這一點,因爲DOM解析器,但是SAX是痛苦的,而不是使用StAX的解析器,它提供了一個更簡單的迭代器接口。 See the answer to another question I provided for an example of how to do this with ColdFusion

這大概你會爲你的例子做什麼:

<cfset fis = createObject("java", "java.io.FileInputStream").init(
    "#getDirectoryFromPath(getCurrentTemplatePath())#/file.xml" 
)> 
<cfset bis = createObject("java", "java.io.BufferedInputStream").init(fis)> 
<cfset XMLInputFactory = createObject("java", "javax.xml.stream.XMLInputFactory").newInstance()> 
<cfset reader = XMLInputFactory.createXMLStreamReader(bis)> 

<cfloop condition="#reader.hasNext()#"> 
    <cfset event = reader.next()> 
    <cfif event EQ reader.START_ELEMENT> 
     <cfswitch expression="#reader.getLocalName()#"> 
      <cfcase value="advs"> 
       <!--- root node, do nothing ---> 
      </cfcase> 
      <cfcase value="advuser"> 
       <!--- set values used later on for inserts, selects, updates ---> 
      </cfcase> 
      <cfcase value="user"> 
       <!--- some selects and insert ---> 
      </cfcase> 
      <cfcase value="vehicle"> 
       <!--- insert or update ---> 
      </cfcase> 
     </cfswitch> 
    </cfif> 
</cfloop> 

<cfset reader.close()> 
+0

是coldfusion的JavaScript兼容環境? – 2011-02-14 18:43:05

1

我相信Cold Fusion XML解析器使用DOM解析,它不適合這種文件大小。你應該試着找到一個SAX解析器,它是事件驅動的。也許這種聯繫將有助於 http://coldfusion.sys-con.com/node/236002

1

我不知道的ColdFusion,但20-30Mb是不是超出範圍爲構建內存樹技術;許多人經常在200Mb文件上運行XSLT轉換。

轉向SAX解析聽起來像是一種極端措施 - 它是一個如此低級的界面。

2

orangepips提供了一個合理的解決方案。請看看Ben Nadel在ColdFusion中處理非常大的XML文件的解決方案。我已經在一個有120萬行的50MB XML文件上測試了他的方法。 Ben使用類似的方法,orangepips在這裏提供 - 使用Java進行流式處理,然後使用XMLParse在ColdFusion中的每個節點進行處理。檢查一下 - 就像Ben Nadel的大部分代碼和教程一樣,它只是起作用。

http://www.bennadel.com/blog/1345-Ask-Ben-Parsing-Very-Large-XML-Documents-In-ColdFusion.htm