2

saxパーサーを使用してJavaのxmlファイルからデータをフェッチしようとしています。少量のデータを取得することに成功しましたが、データが大きくなりすぎて複数行になると、すべての行ではなく、2行のデータしか表示されません。私は次のコードを試しています-

InputStreamReader isr = new InputStreamReader(is);
InputSource source = new InputSource(isr);
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
SAXParser parser = factory.newSAXParser();
XMLReader xr = parser.getXMLReader();
GeofenceParametersXMLHandler handler = new GeofenceParametersXMLHandler();
xr.setContentHandler(handler);
xr.parse(source);

そして私のGeofenceParametersXMLHandlerは-

private boolean inTimeZone = false;
private boolean inCoordinate = false;
private boolean outerBoundaryIs = false;
private boolean innerBoundaryIs = false;
private String timeZone;
private List<String> innerCoordinates = new ArrayList<String>();
private String outerCoordinates;

public String getTimeZone() {
    return timeZone;
}

public List<String> getInnerCoordinates() {
    return innerCoordinates;
}

public String getOuterCoordinates() {
    return outerCoordinates;
}

@Override
public void characters(char[] ch, int start, int length) throws SAXException {
    super.characters(ch, start, length);
    if (this.inTimeZone) {
        this.timeZone = new String(ch, start, length);
        this.inTimeZone = false;
    }

    if (this.inCoordinate && this.innerBoundaryIs) {
        this.innerCoordinates.add(new String(ch, start, length));
        this.inCoordinate = false;
        this.innerBoundaryIs = false;
    }

    if (this.inCoordinate && this.outerBoundaryIs) {
        this.outerCoordinates = new String(ch, start, length);
        this.inCoordinate = false;
        this.outerBoundaryIs = false;
    }
}

@Override
public void endElement(String uri, String localName, String name) throws SAXException {
    super.endElement(uri, localName, name);
}

@Override
public void startDocument() throws SAXException {
    super.startDocument();
}

@Override
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
    super.startElement(uri, localName, name, attributes);

    if (localName.equalsIgnoreCase("timezone")) {
        this.inTimeZone = true;
    }

    if (localName.equalsIgnoreCase("outerBoundaryIs")) {
        this.outerBoundaryIs = true;
    }

    if (localName.equalsIgnoreCase("innerBoundaryIs")) {
        this.innerBoundaryIs = true;
    }

    if (localName.equalsIgnoreCase("coordinates")) {
        this.inCoordinate = true;
    }
}

そして、xmlファイルは-

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2"
xmlns:gx="http://www.google.com/kml/ext/2.2">

<Placemark>
   <name>gx:altitudeMode Example</name>
   <timezone>EASTERN</timezone>
   <Polygon>
      <extrude>1</extrude>
      <altitudeMode>relativeToGround</altitudeMode>
      <outerBoundaryIs>
      <LinearRing>
         <coordinates>
        -77.05788457660967,38.87253259892824,100 
        -77.05465973756702,38.87291016281703,100 
        -77.05315536854791,38.87053267794386,100 
        -77.05552622493516,38.868757801256,100 
        -77.05844056290393,38.86996206506943,100 
        -77.05788457660967,38.87253259892824,100
      </coordinates>
    </LinearRing>
  </outerBoundaryIs>
</Polygon>

私はいつも座標の2行のデータを取得しました。しかし、それらが1行になっていると、完全なデータが得られました。複数行で完全なデータをフェッチする方法は?

前もって感謝します。

4

1 に答える 1

8

このcharacters()方法では、必ずしもすべてのテキストデータが一度に提供されるとは限りません(これは非常に一般的な誤解ですが)。

適切なアプローチは、characters()への連続した呼び出しによって返されるすべてのデータを連結することです(StringBuilderまたは同様のものを使用して)。endElement()メソッドが呼び出されると、そのテキストバッファを完全なものとして扱い、そのように処理できます。

ドキュメントから:

パーサーはこのメソッドを呼び出して、文字データの各チャンクを報告します。SAXパーサーは、連続するすべての文字データを1つのチャンクで返す場合もあれば、複数のチャンクに分割する場合もあります。

多くの場合、小さなXMLドキュメントの場合は1回の呼び出しでcharacters()十分です。ただし、XMLドキュメントのサイズが大きくなると、バッファリングなどが原因で複数の呼び出しが発生し始めることがわかります。その結果、それ自体で処理される各呼び出しは不完全であるように見えます。

于 2012-08-14T11:00:04.970 に答える