1

次のように、対応する緯度と経度を含む郵便番号を含む一連の XML があります。

<?xml version="1.0"?>
<postcodes>
    <entry postcode='AB1 0AA' latitude='7.101478' longitude='2.242852' />
    <entry postcode='AB1 0AB' latitude='7.201458' longitude='2.122952' />
</postcodes>

XML は特定の文字で始まる郵便番号に分割されるため、アルファベットの文字ごとに 1 つの XML があります。それらの間には、英国内のすべての郵便番号が含まれています。つまり、これらの XML ファイルの最大のものには 300,000entryの要素が含まれています。

Entity オブジェクトのリストをループして、郵便番号を SAX 経由で配置し、各郵便番号に対してlongitudeとのlatitude値を取得しています。したがって、2000 個のエンティティ オブジェクトがある場合、SAX ハンドラを 2000 回実行してそれらの値を取得します。以下のループのコード。

em = emf.createEntityManager();

    for (Integer id : siteID){ 
            site = em.find(SiteTable.class, id);
            if(site != null && site.getPostcode() != null && !site.getPostcode().equals("")){
                XMLPositionRetriever.runXMLQuery(site.getPostcode()); 
            }
            else{
                System.out.println("The site and/or postcode against this Instruction does not exist.");
            }
     }
em.close();

site.getPostcode()postcodeToFindHandler になります。以下で使用されている唯一の SAX Handler メソッドのコード。

@Override 
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    if (postcodeToFind.equals(attributes.getValue("postcode"))){
        System.out.println("The postcode '"+postcodeToFind+"', has a latitude of "+attributes.getValue("latitude")+" and a longitude of "+attributes.getValue("longitude"));
        throw new SAXException();   
    }      
}

現在、これには時間がかかります (2000 回の検索で 4 分弱かかります) が、ロード時間を速くする必要があります。できれば30秒以内。これまでのところ、ロード時間を半分以下に短縮することができました。

  • Handler を実行しなければならない回数を、必要な回数だけに削減します (チェックする必要のあるエンティティの数を減らすことによって)。
  • 必要なデータが見つかったら startElement() メソッドで例外をスローするようにして、不必要に検索を続けないようにします。
  • XML ファイルを小さなファイル (アルファベットの文字ごとに 1 つ) に分割して、ハンドラーがファイルごとにチェックする要素を少なくします。

Q: SAX をより効率的に処理するための提案はありますか?

4

1 に答える 1

2

地理的位置を取得するすべての郵便番号をハンドラーに渡すことができれば、ハンドラーはそれらを一度に取得できます。これを行う SAXHandler は次のようになります。

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SAXDemo extends DefaultHandler {

  private Map<String, Location> postalCodeMap;

  static class Location {
    String latitude;

    String longitude;
  }

  public SAXDemo(List<String> postalCodes) {
    this.postalCodeMap = new HashMap<String, SAXDemo.Location>();
    for (String postalCodeToLookFor : postalCodes) {
      this.postalCodeMap.put(postalCodeToLookFor, new Location());
    }
  }

  @Override
  public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    String postCodeOfElem = attributes.getValue("postcode");
    if (postCodeOfElem != null && this.postalCodeMap.containsKey(postCodeOfElem)) {
      Location loc = this.postalCodeMap.get(postCodeOfElem);
      loc.latitude = attributes.getValue("latitude");
      loc.longitude = attributes.getValue("longitude");
    }
  }

  public Location getLocationForPostalCode(String postalCode) {
    return this.postalCodeMap.get(postalCode);
  }

  public Map<String, Location> getAllFoundGeoLocations() {
    return this.postalCodeMap;
  }
}

ここでは、ハンドラーのコンストラクターに文字列のリストを渡し、ハンドラーがすべての XML データを使用してドキュメントを解析できるようにします。解析が完了すると、取得されたすべての地理的位置がpostalCodeMap

于 2013-09-04T12:30:14.700 に答える