2012-02-13 70 views
4

我正在使用VTD-XML解析許多XML文件。我不確定我是否正確使用了該工具 - 我認爲是這樣,但解析這些文件讓我過了很久。使用VTD-XML優化解析XML文件的速度

xml文件(DATEXII格式)是HD上的壓縮文件。解壓縮它們大約31MB,包含超過850.000行文本。我只需要提取幾個字段並將它們存儲在數據庫中。

import org.apache.commons.lang3.math.NumberUtils; 
... 

private static void test(File zipFile) throws XPathEvalException, NavException, XPathParseException { 
    // init timer 
    long step1=System.currentTimeMillis(); 

    // open file to output extracted fragments 
    VTDGen vg = new VTDGen(); 
    vg.parseZIPFile(zipFile.getAbsolutePath(), zipFile.getName().replace(".zip",".xml"),true); 

    VTDNav vn = vg.getNav(); 

    AutoPilot apSites = new AutoPilot(); 
    apSites.declareXPathNameSpace("ns1", "http://schemas.xmlsoap.org/soap/envelope/"); 
    apSites.selectXPath("/ns1:Envelope/ns1:Body/d2LogicalModel/payloadPublication/siteMeasurements"); 
    apSites.bind(vn); 

    long step2=System.currentTimeMillis(); 
    System.out.println("Prep took "+(step2-step1)+"ms; "); 

    // init variables 
    String siteID, timeStr; 
    boolean reliable; 
    int index, flow, ctr=0; 
    short speed; 
    while(apSites.evalXPath()!=-1) { 

     vn.toElement(VTDNav.FIRST_CHILD, "measurementSiteReference"); 
     siteID = vn.toString(vn.getText()); 

     // loop all measured values of this measurement site 
     while(vn.toElement(VTDNav.NEXT_SIBLING, "measuredValue")) { 
      ctr++; 

      // extract index attribute 
      index = NumberUtils.toInt(vn.toString(vn.getAttrVal("index"))); 

      // go one level deeper into basicDataValue 
      vn.toElement(VTDNav.FIRST_CHILD, "basicDataValue"); 

      // we need either FIRST_CHILD or NEXT_SIBLING depending on whether we find something 
      int next = VTDNav.FIRST_CHILD; 
      if(vn.toElement(next, "time")) { 
       timeStr = vn.toString(vn.getText()); 
       next = VTDNav.NEXT_SIBLING; 
      } 

      if(vn.toElement(next, "averageVehicleSpeed")) { 
       speed = NumberUtils.toShort(vn.toString(vn.getText())); 
       next = VTDNav.NEXT_SIBLING; 
      } 

      if(vn.toElement(next, "vehicleFlow")) { 
       flow = NumberUtils.toInt(vn.toString(vn.getText())); 
       next = VTDNav.NEXT_SIBLING; 
      } 

      if(vn.toElement(next, "fault")) { 
       reliable = vn.toString(vn.getText()).equals("0"); 
      } 

      // insert into database here... 

      if(next==VTDNav.NEXT_SIBLING) { 
       vn.toElement(VTDNav.PARENT); 
      } 
      vn.toElement(VTDNav.PARENT); 
     } 

    } 
    System.out.println("Loop took "+(System.currentTimeMillis()-step2)+"ms; "); 
    System.out.println("Total number of measured values: "+ctr); 
} 

我的XML的文件準確上述功能的輸出是:

Prep took 25756ms; 
Loop took 26889ms; 
Total number of measured values: 112611 

沒有數據實際上是插入到數據庫中現在。現在問題是我每分鐘收到一個這樣的文件。現在總解析時間將近1分鐘,而且由於下載文件需要大約10秒鐘,而且我需要將數據存儲在數據庫中,所以我現在正在實時運行。

有什麼辦法可以加快速度嗎?事情我已經試過了沒有幫助:

  • 所有字段使用自動駕駛儀,這實際上是由第二步速度慢一些30000ms
  • 解壓文件自己並解析字節數組VTD,這次沒任何區別
  • 循環使用自己一個BufferedReader的readLine()的文件,但這是不夠快或者

是否有人看到一種可能性,加快速度,或者我需要開始思考一個更重的機器/多線程?當然,每分鐘850.000行(每天12億行)是很多,但我仍然認爲它不應該花一分鐘來解析31MB的數據...

+0

你可以將問題發佈到vtd-xml郵件列表,我很樂意幫你解決問題。 – 2012-07-15 05:28:07

回答

1

你可以嘗試解壓文件夾右客場與

File[] files = new File("foldername").listFiles(); 

存儲每個XML文件的值數組,然後你可以做一個循環,通過每一個文件去,林不知道這是否會加快步伐,但它值得一試。