2

我是 Java 的新手,在评估了一些 Java 库后,我通过性能测试和使用 Xpath 的选项选择了 VTD-XML,我尝试了 StaX,我认为它不适合人类,真的很难理解解析是如何工作的(几乎对我来说XD)。

所以,我的目标是将 geo_code 节点从 partial_geo_codes.xml “注入”到 geo_code accommodation.xml 中,匹配节点 ext_id 上的值

住宿.xml

<accommodations>
 <accommodation>
  <ext_id>12345</ext_id>
  <type>A</type>
  <details>D</details>
  <geo_code />
  </accommodation>

这是要附加到住宿.xml 中的文件:

partial_geo_codes.xml

<geo_codes>
 <geo_code>
  <ext_id>12345</ext_id>
  <geo_idlocacion>77500</geo_idlocacion>
  <latitude>42.578114</latitude>
  <longitude>1.648293</longitude>
  </geo_code>
  <geo_code>
      ...
  <geo_code>
  <geo_code>
      ...
  <geo_code>
 <geo_codes>

这是预期的输出:

住宿新的.xml

<accommodations>
 <accommodation>
  <ext_id>12345</ext_id>
  <type>A</type>
  <details>D</details>
  <geo_code>
    <ext_id>12345</ext_id>
    <geo_idlocacion>77500</geo_idlocacion>
    <latitude>42.578114</latitude>
    <longitude>1.648293</longitude>
  <geo_code> 
  </accommodation>
  <accommodation>
   .....
  </accommodation>
  ...... 
</accommodations>

这是我的“wannabe-really-sucks”java类:

import com.ximpleware.extended.*;
import java.io.*;

public class MergeVtd  {

 public static void main(String args[]) throws Exception {

    String filesPath = new java.io.File("").getAbsolutePath() .concat("/main/src/");
    long start = System.currentTimeMillis();


    //init original xml
    VTDGenHuge vgh = new VTDGenHuge();
    //init tobemerged xml
    VTDGenHuge vgm = new VTDGenHuge();


    if (vgm.parseFile(filesPath.concat("partial_geo_code.xml"),true,VTDGenHuge.MEM_MAPPED)){

        VTDNavHuge vnm = vgm.getNav();
        AutoPilotHuge apm = new AutoPilotHuge(vnm);
        apm.selectElement("ext_id");


        int  count=0;
        while (apm.iterate()){
            int t = vnm.getText();
            if (t!=-1)    {
                System.out.println("Value vnm ==> "+vnm.toNormalizedString(t));

            //we have id to match....

            if (vgh.parseFile(filesPath.concat("accommodation.xml"),true,VTDGenHuge.MEM_MAPPED)){
                VTDNavHuge vnh = vgh.getNav();
                AutoPilotHuge aph = new AutoPilotHuge(vnh);
                aph.selectXPath("/accommodations/accommodation/ext_id[text()='" + vnm.toNormalizedString(t) + "']" );


                int result = -1;
                while ((result=aph.evalXPath())!=-1){
                    int g = vnh.getText();
                    if (g!=-1)  {
                        System.out.println("Value vnh ==> "+vnh.toNormalizedString(g));

                    }  else {
                        System.out.println("no match in vnh !======= ");
                    }
                }
            }

            }

            System.out.println("============================== " + count);
            count++;

        }

    }

    long end = System.currentTimeMillis();
    System.out.println("Execution time was "+ (end - start) +" ms.");
    System.exit(0);

 }

}

我真的很感激任何线索帮助我如何一次迭代到 2 个 xml 文件并更快地按 ext_id 节点值合并,现在真的需要太多时间。

4

1 回答 1

1

partial_geo_codes.xml 有多大?它可以放在内存中吗?如果是,那么我建议使用哈希映射对其进行索引。只需创建简单的 HashMap,并将对 geo_code 节点的引用以 ext_id 作为键。

完成后,您只需要传递一次 accomodations.xml。现在你的算法复杂度是 O(n^2),更糟糕的是涉及从磁盘读取 n 次!带有 HashMap 的版本将花费 O(n) 时间,并且只需要一次通过两个 xml 文件。

于 2012-09-11T19:32:19.733 回答