2

巨大な(約500mb)ファイルからXMLを抽出する必要がありますが、32ビットのJVMがあり、常にヒープスペースが不足しています。

このファイルからXMLを抽出するプログラムを作成しましたが、そのためにはファイル全体を読み取る必要があります(100行目が終了するかどうかを確認できないため、反復ごとに100行程度で処理することはできません。 XML)。

だから私はそれをどのように行うのですか?

抽出のための私のプログラム:

private static ArrayList<String> extractXml(String xml) {
    String[] newXml = xml.split("\\<\\?");
    ArrayList<String> xmlList = new ArrayList<String>(Arrays.asList(newXml));
    for(int i = 0; i<xmlList.size();i++){
        if(!xmlList.get(i).contains("xml version=\"1.0\" encoding=\"UTF-8\"")){
            xmlList.remove(i);
        }
    }
    int size = xmlList.size();
    if(xml.contains("#"))
    for(int j = 0;j<size;j++){
        xmlList.set(j, "<?"+xmlList.get(j));
        xmlList.set(j,xmlList.get(j).split("\\#")[0]);

    }else
        for(int j = 0;j<size;j++){
            xmlList.set(j, "<?"+xmlList.get(j).trim());
            System.out.println(xmlList.get(j));             
        }



    return xmlList;

}

XMLにはヘッダー(JMSStreamヘッダー。XMLのラッパーのようなもの)もあり、上記のロジックを使用して正常に削除しています。

サンプルファイルの内容:

#---------- #2 : ID:QADC1_HGR1-EMS13112.15DB4FBEA3665328B:4985 ----------#
<MSG_INFO>
    <message type="TextMessage" messageSelector="" receiveTime="2012-09-12T14:37:26.717" jmsServerTimestamp="2012-09-12T14:37:26.775">
        <header JMSMessageID="ID:QADC1_HGR1-EMS13112.15DB4FBEA3665328B:4985" JMSDestination="OPS.FPES.OUTBOUND.FLIGHT.TRACK_A.DISTRIBUTION" JMSDestinationType="Topic" JMSDeliveryMode="2" JMSPriority="4" JMSTimestamp="1347478646775"/>
        <properties>
            ...
        </properties>
    </message>
</MSG_INFO>
BodyLength=31108
<?xml version="1.0" encoding="UTF-8"?>

<ns0:Envelope xmlns:ns0="http://www.wnco.com/opsplatform/flight/flightevent">
    <ns0:Header>
        <ns1:EventHeader xmlns:ns1="http://www.wnco.com/opsplatform/event/header">
            ...
        </ns1:EventHeader>
    </ns0:Header>
    <ns0:Body>
        <ns1:Flight xmlns:ns1="http://www.wnco.com/opsplatform/flight/flight">
           <ns2:ScheduledFlightLeg xmlns:ns2="http://www.wnco.com/opsplatform/flight/flight/scheduledflightleg">
                ...
                <ns3:OperationalFlightLeg xmlns:ns3="http://www.wnco.com/opsplatform/flight/flight/operationalflightleg">
                    ...
                </ns3:OperationalFlightLeg>
            </ns2:ScheduledFlightLeg>
            <ns2:ScheduledFlightLeg xmlns:ns2="http://www.wnco.com/opsplatform/flight/flight/scheduledflightleg">
                ...
                    ...
                </ns3:OperationalFlightLeg>
            </ns2:ScheduledFlightLeg>
            <ns2:ScheduledFlightLeg xmlns:ns2="http://www.wnco.com/opsplatform/flight/flight/scheduledflightleg">
               ...
                    ...
                </ns3:OperationalFlightLeg>
            </ns2:ScheduledFlightLeg>
            <ns2:ScheduledFlightLeg xmlns:ns2="http://www.wnco.com/opsplatform/flight/flight/scheduledflightleg">
                ...
                    ...
                </ns3:OperationalFlightLeg>
            </ns2:ScheduledFlightLeg>
        </ns1:Flight>
    </ns0:Body>
</ns0:Envelope>

#---------- #3 : ID:QADC1_HGR1-EMS13112.15DB4FBEA3665328B:4985 ----------#
        <MSG_INFO>
            <message type="TextMessage" messageSelector="" receiveTime="2012-09-12T14:37:26.717" jmsServerTimestamp="2012-09-12T14:37:26.775">
                <header JMSMessageID="ID:QADC1_HGR1-EMS13112.15DB4FBEA3665328B:4985" JMSDestination="OPS.FPES.OUTBOUND.FLIGHT.TRACK_A.DISTRIBUTION" JMSDestinationType="Topic" JMSDeliveryMode="2" JMSPriority="4" JMSTimestamp="1347478646775"/>
                <properties>
                    ...
                </properties>
            </message>
        </MSG_INFO>
        BodyLength=31108
        <?xml version="1.0" encoding="UTF-8"?>

        <ns0:Envelope xmlns:ns0="http://www.wnco.com/opsplatform/flight/flightevent">
            <ns0:Header>
                <ns1:EventHeader xmlns:ns1="http://www.wnco.com/opsplatform/event/header">
                    ...
                </ns1:EventHeader>
            </ns0:Header>
            <ns0:Body>
                <ns1:Flight xmlns:ns1="http://www.wnco.com/opsplatform/flight/flight">
                   <ns2:ScheduledFlightLeg xmlns:ns2="http://www.wnco.com/opsplatform/flight/flight/scheduledflightleg">
                        ...
                        <ns3:OperationalFlightLeg xmlns:ns3="http://www.wnco.com/opsplatform/flight/flight/operationalflightleg">
                            ...
                        </ns3:OperationalFlightLeg>
                    </ns2:ScheduledFlightLeg>
                    <ns2:ScheduledFlightLeg xmlns:ns2="http://www.wnco.com/opsplatform/flight/flight/scheduledflightleg">
                        ...
                            ...
                        </ns3:OperationalFlightLeg>
                    </ns2:ScheduledFlightLeg>
                    <ns2:ScheduledFlightLeg xmlns:ns2="http://www.wnco.com/opsplatform/flight/flight/scheduledflightleg">
                       ...
                            ...
                        </ns3:OperationalFlightLeg>
                    </ns2:ScheduledFlightLeg>
                    <ns2:ScheduledFlightLeg xmlns:ns2="http://www.wnco.com/opsplatform/flight/flight/scheduledflightleg">
                        ...
                            ...
                        </ns3:OperationalFlightLeg>
                    </ns2:ScheduledFlightLeg>
                </ns1:Flight>
            </ns0:Body>
        </ns0:Envelope>
4

3 に答える 3

1

JAVAスキャナーを使用して、XMLごとの一意のプロパティに基づいてXMLを抽出します。

 public static void main(String[] args) {
      String temp = null;
      String searchedData = null;
      File file = new File(fileLocation);
      try{
            Scanner scan = new Scanner (file);
            scan.useDelimiter("xml version");
            while (scan.hasNext()){
                  temp = scan.next();
                  if(temp.contains("<ns1:EventCorrelationID>153721264</ns1:EventCorrelationID>")){
                        searchedData = temp.substring(0, temp.lastIndexOf("</ns0:Envelope>")+15);
                        System.out.println("xml version"+searchedData);
                  }
            }
      }catch(Exception e){
            e.printStackTrace();
      }
}
于 2012-09-20T15:54:41.270 に答える
0

本当にSAXパーサーを使用する必要があります。SAXパーサーは、ドキュメント全体を一度に読み取るのではなく、要素を順番に読み取ります。読み取り時にのみメモリにロードされます。これは、あなたがやろうとしていることやDOMパーサーとは反対です。

于 2012-09-20T14:42:55.707 に答える
0

確かに、500MbのデータをJava文字列にロードしてから、文字列に正規表現を適用することによってそれを行うべきではありません。これは、あなたが行っているように見えることです。ファイルのバッファ読み取りを実行し、各バッファの内容を調べて、あるバッファから次のバッファへの境界にまたがる区切り文字をチェックするように注意する必要があります。

于 2012-09-20T15:31:41.137 に答える