2

私は Java の初心者です。いくつかの Java ライブラリを評価した後、パフォーマンス テストと Xpath を使用するオプションによって VTD-XML を選択しました。StaX を試してみましたが、解析がどのように機能するかを理解するのは本当に難しいと思います。私にとってはXD)。

したがって、私の目標は、partial_geo_codes.xml の geo_code ノードを、両方のノード ext_id の値に一致する geo_code accommodation.xml に「注入」することです。

宿泊施設.xml

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

これは、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>

これは期待される出力です:

宿泊施設_new.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>

そして、これは私の「本当に嫌な」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 を作成し、ext_id の値をキーとして geo_code ノードへの参照を配置します。

これが完了したら、accomodations.xml を 1 回だけ渡す必要があります。現在、アルゴリズムの複雑さは O(n^2) ですが、さらに悪いことに、ディスクから n 回の読み取りが必要です! HashMap を含むバージョンは O(n) 時間かかり、両方の xml ファイルを 1 回だけ通過する必要があります。

于 2012-09-11T19:32:19.733 に答える