2011-03-15 5 views
1

작은 파일로 분할해야하는 큰 (1GB) 파일이 있습니다. 작은 파일마다 <OFFER> 태그 중 500 개를 포함하고 싶습니다. XML 파일을 각각 500 개의 태그가있는 여러 파일로 분할

<?xml version="1.0"?><RESULT> 
<header> 
    <site>http://www.thomascook.fr</site> 
    <marque>ThomasCook France</marque> 
    <logo>http://www.example.com/example.gif</logo> 
</header> 
<OFFER> 
    <IFF>5810</IFF> 
    <TO>TCF</TO> 
    <COUNTRY>Chypre</COUNTRY> 
    <REGION>Chypre du Sud</REGION> 
    <HOTELNAME>Elias Beach &amp; Country Club</HOTELNAME> 
    <DESCRIPTION>....</DESCRIPTION> 
    <TYPE>Sejour</TYPE> 
    <STARS>5.0</STARS> 
    <THEMAS>Plage directe;Special enfant;Bien-Etre-Fitness</THEMAS> 
    <THUMBNAIL>http://example.com/example.jpg</THUMBNAIL> 
    <URL>http://example.com/example.html</URL> 
    <DATE> 
     <BROCHURE>TCFB</BROCHURE> 
     <DURATION>7</DURATION> 
     <DURATION_VAR>6_6-9</DURATION_VAR> 
     <BOARD>Demi-pension</BOARD> 
     <DEPARTURE>27.2.2011</DEPARTURE> 
     <RETURN>6.3.2011</RETURN> 
     <DEPARTURE_CITY>PAR</DEPARTURE_CITY> 
     <ARRIVAL_CITY>LCA</ARRIVAL_CITY> 
     <PRICE>790</PRICE> 
     <URL>http://example.com/other-example.html</URL> 
    </DATE> 
</OFFER> 
<OFFER> 
    (etc) 
</OFFER> 

나는이 어떻게 할 수있는

: 여기

은 큰 XML 파일의 작은 조각이다?

+1

우리가 읽을 수 있도록 XML을 들여 씁니다. –

+0

어떤 프로그래밍 언어를 사용하고 있습니까? 아니면 사용할 수 있습니까? –

+0

Stax with java를 사용합니다 – timo

답변

2

영어로 큰 XML 파일을 여러 개의 작은 파일로 분할하고 싶습니다. 가장 좋은 하나가 다음 코드는 XPath를 기반으로 큰 XML을 분할합니다, http://vtd-xml.sourceforge.net/

샘플 코드입니다, TopTag/ChildTag 프로그래밍 질문으로


import java.io.File; 
import java.io.FileOutputStream; 

import com.ximpleware.AutoPilot; 
import com.ximpleware.FastLongBuffer; 
import com.ximpleware.VTDGen; 
import com.ximpleware.VTDNav; 

// This example shows how to split XML 
public class Split { 
    public static void main(String[] args) { 
     String prefix = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<TopTag xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n"; 
     String suffix = "\n</TopTag<"; 
     try { 

      VTDGen vg = new VTDGen(); 
      if (vg.parseFile(args[0], false)) { 
       int splitBy = Integer.parseInt(args[1]); 
       String filePrefix = args[2]; 
       VTDNav vn = vg.getNav(); 
       AutoPilot ap = new AutoPilot(vn); 
       ap.selectXPath("/TopTag/ChildTag"); 
       // flb contains all the offset and length of the segments to be 
       // skipped 
       FastLongBuffer flb = new FastLongBuffer(4); 
       int i; 
       byte[] xml = vn.getXML().getBytes(); 
       while ((i = ap.evalXPath()) != -1) { 
        flb.append(vn.getElementFragment()); 
       } 
       int size = flb.size(); 
       if (size != 0) { 
        File fo = null; 
        FileOutputStream fos = null; 
        for (int k = 0; k < size; k++) { 
         if (k % splitBy == 0) { 
          if (fo != null) { 
           fos.write(suffix.getBytes()); 
           fos.close(); 
           fo = null; 
          } 
         } 
         if (fo == null) { 
          fo = new File(filePrefix + k + ".xml"); 
          fos = new FileOutputStream(fo); 
          fos.write(prefix.getBytes()); 
         } 
         fos.write(xml, flb.lower32At(k), flb.upper32At(k)); 
        } 
        if (fo != null) { 
         fos.write(suffix.getBytes()); 
         fos.close(); 
         fo = null; 
        } 
       } 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+1

제 생각에 vdt-xml은 전체 XML 문서를 메모리에로드하여 작동합니다. 메모리를 효율적으로 사용한다고 주장하는 동안 자체 견적을 통해 1Gb XML 문서에 대해 최대 1.5Gb 힙이 필요할 수 있습니다. –

+0

@stephenC - 메모리 매핑 모드에서 확장 된 vtd-xml을 사용할 수 있습니다 ... –

2

,이 프로그래밍 STAX 의 문제이다.

모든 500 요소는 요소와 문서를 끝내고 파일을 닫고 새 파일을 열고 새 파일을 시작한 다음 계속하기 위해 필요한 호출을합니다. stax에 하나의 파일을 쓸 수있는 프로그램이 있다면 많은 것을 작성하는 것과 별반 다르지 않습니다.

관련 문제