2017-07-31 166 views
3

我使用XPath從XML文件中提取大型塊。我的XML文件很大,它們來自PubMed。我的文件類型的一個例子是:從大型xml文件中提取大型xml塊的最佳方法

ftp://ftp.ncbi.nlm.nih.gov/pubmed/baseline/medline17n0001.xml.gz

因此,通過使用

Node result = (Node)xPath.evaluate("PubmedArticleSet/PubmedArticle[MedlineCitation/PMID = "+PMIDtoSearch+"]", doc, XPathConstants.NODE); 

我得到PMIDtoSearch的文章,所以它的完美。但這需要很多時間。我必須做大約800,000次,所以這個解決方案需要兩個多月的時間。有些塊有超過400行,每個xml文件有超過4百萬行。

我也嘗試過這樣的解決方案getElementsByTagName函數,但它幾乎需要相同的時間。

您是否知道如何改進解決方案?

謝謝。

+0

VTD-XML是這個最終的XML解析器我將很快作出貢獻的一段代碼給你。 –

+0

我會編寫XQuery來抓取GZIP,解壓縮並存儲到存在數據庫中。然後針對該存儲文檔編寫Xquery。 –

回答

3

我把你的文件,並加載到存在-DB然後執行查詢,基本上是這樣的:

xquery version "3.0"; 
let $medline := '/db/Medline/Data' 
let $doc := 'medline17n0001.xml' 
let $PMID := request:get-parameter("PMID", "") 
let $article := doc(concat($medline,'/',$doc))/PubmedArticleSet/PubmedArticle[MedlineCitation/PMID=$PMID] 
return 
$article 

該文件從遠程服務器返回的400毫秒。如果我加強了這個服務器,我希望少於這個,它可以處理多個併發請求。或者,如果你擁有本地更快的一切。

自己試試吧,我留在測試服務器上的數據(請記住,這是遠程查詢到在加州亞馬遜微型服務器):

http://54.241.15.166/get-article2.xq?PMID=8

http://54.241.15.166/get-article2.xq?PMID=6

http://54.241.15.166/get-article2.xq?PMID=1

當然,整個文檔都在那裏。您可以將該查詢更改爲PMID = 667或999或其他任何值,然後將目標文檔片段返回。

0

這是執行xpath查詢的代碼..在我的筆記本電腦上,結果看起來很不錯..花了約1秒,不管pmid值多少。你打算如何提取文本。我可以更新代碼以達到目標。

public static void main(String[] args) throws VTDException{ 
     VTDGen vg = new VTDGen(); 
     if (!vg.parseFile("d:\\xml\\medline17n0001.xml", false)) 
      return; 
     VTDNav vn = vg.getNav(); 
     AutoPilot ap = new AutoPilot(vn); 
     System.out.println("nesting level"+vn.getNestingLevel()); 
     String PMIDtoSearch = "30000"; 
     ap.selectXPath("/PubmedArticleSet/PubmedArticle[MedlineCitation/PMID = "+PMIDtoSearch+"]"); 
     System.out.println("====>"+ap.getExprString()); 
     int i=0,count=0; 
     System.out.println(" token count ====> "+ vn.getTokenCount()); 
     while((i=ap.evalXPath())!=-1){ 
      count++; 
      System.out.println("string ====>"+vn.toString(i)); 
     } 
     System.out.println(" count ===> "+count); 
    } 
2

正如@凱文布朗所言,數據庫可能是正確的答案。但是,如果這是一次性過程,那麼可能存在的解決方案比您的解決方案快得多,但不需要學習如何設置XML數據庫的複雜性。

在您使用的方法中,存在兩個主要成本:解析XML文檔以在內存中創建樹,然後搜索內存中文檔以查找特定ID值。我猜測解析成本可能比搜索成本高一個數量級。

所以有兩種成分,以獲得良好的性能這一點:

  • 首先,你需要確保你只解析每個源文件一次(而不是每一次查詢)。你還沒有告訴我們足以讓我能夠分辨你是否已經這樣做。第二,如果您要從單個文檔中檢索許多數據塊,則需要在不對每個文檔執行串行搜索的情況下執行此操作。實現此目的的最佳方法是使用查詢處理器來構建索引以優化查詢(如Saxon-EE)。或者,您可以「手動」構建索引,例如使用XQuery 3.1映射或使用XSLT中的xsl:key功能。

+0

它是一個很好的觀點。那些我熟悉的數據集。它大約有21,000 MB的數據。如果是一次處理它,也許。然後再次,我可以作弊,因爲我有一個偉大的亞馬遜服務器映像,具有存儲數據庫和更多的加載,我可以在5分鐘內啓動。 –