1

VTD-XML を使用して、大きな xml ファイルを小さな xml ファイルに分割しています。すべてがうまく機能します:

autoPilot.selectXPath("//nodeName")

何らかの理由で最初の 3 つのノードをスキップしています。

LOG.info("xpath has found "+ ap.evalXPath() +" items");編集: vtd-xml-authorは、カウントを返さずにノード インデックスを返すことを指摘しました。

新しい分割 xml ファイルには、元のファイルの最初の 3 つのノードがありません。

これが基本的な XML レイアウトです。本当の xml データを表示することはできませんが、次のようになります。

<rootNode>
          <parentNode>
                      <contentNode>..children inside...</contentNode>
                      <contentNode>..children inside...</contentNode>
                      <contentNode>..children inside...</contentNode>
                      <contentNode>..children inside...</contentNode>
          </parentNode>
</rootNode>

そして、ここに私がxmlを分割するために使用している関数があります:

public void splitXml(String parentNode, String contentNodes)throws Exception {
    LOG.info("Splitting " + outputName + parentNode);
    VTDGen vg = new VTDGen();   

     if (vg.parseFile(xmlSource, true)){

        VTDNav vn = vg.getNav();
        AutoPilot ap = new AutoPilot(vn);
        ap.selectXPath("//"+contentNode);

        int i=-1;
        int k=0;
        byte[] ba = vn.getXML().getBytes();
        FileOutputStream fos = getNewXml(parentNode);
        while((i=ap.evalXPath())!=-1){

            if(fos.getChannel().size() > maxFileSize){
                finishXml(fos,contentNode);
                LOG.info("Finished file with " + k + "nodes");
                fos = getNewXml(contentNode);
                k=0;
            }
            k++;
            long l = vn.getElementFragment();
            fos.write(ba, (int)l, (int)(l>>32));
            fos.write("\n".getBytes());
        }
        finishXml(fos,contentNode);
        LOG.info("Finished Splitting " + outputName + " " + parentNode + " with " +k+ " nodes");
    } else {
        LOG.info("Parse Failed");
    }


}

編集: while ループに対抗して追加されました。

4

1 に答える 1

1

提案さvtd-xml-authorれたように、while ループにカウンターを追加しました。

        while((i=ap.evalXPath())!=-1){
            // if filesize is at max create a new File
            if(fos.getChannel().size() > maxFileSize){
                finishXml(fos,contentNode);
                LOG.info("Finished file with " + k + "nodes");
                fos = getNewXml(contentNode);
                k=0;

            }
            k++;
            long l = vn.getElementFragment();
            fos.write(ba, (int)l, (int)(l>>32));
            fos.write("\n".getBytes());
        }

初めて実行したとき、出力には1レコードしかありませんでした。次に、出力 xml ファイルとフォルダーを削除し、スプリッターを再実行しました。今回は、ログに正しい番号が返され、ファイルが正しく分割されました。作成したフォルダとファイルを削除しながら、またファイルを削除せずに、プロセスを何度も繰り返しました。毎回同じ正しい結果が得られました。IDE か何かが正しく更新されていないと推測しています。

于 2012-10-30T22:13:16.287 に答える