2016-07-28 3 views
-1

私はサイズが10gbの大きなxmlファイルを持っています。大きなファイルの最初のレコードから生成された新しいxmlファイルを作成したいと思います.iはjavaとpythonでこれをやろうとしましたが、データ全体を読み込みます。別のポストでメモリエラーを起こさずにサイズ10GBの大きなxmlファイルから最初のレコードを取得してxmlファイルを生成する方法は?

、誰かがXSLTは、XSLTに新しいthis.I'mための最適なソリューションです示唆し、私はplsはこれを行うには、いくつかのスタイルシートを提案し、XSLTでこれを行う方法がわからない...

大規模なXMLファイル(10ギガバイト)サンプル:

<MemberDataExport xmlns="http://www.payback.net/lmsglobal/batch/memberdataexport" xmlns:types="http://www.payback.net/lmsglobal/xsd/v1/types"> 
    <MembershipInfoListItem> 
     <MembershipIdentifier>PB00000000001956044</MembershipIdentifier> 
     <ParticipationStatus>1</ParticipationStatus> 
     <DataSharing>1</DataSharing> 
     <MasterInfo> 
      <Gender>1</Gender> 
      <Salutation>1</Salutation> 
      <FirstName>Hazel</FirstName> 
      <LastName>Sweetman</LastName> 
      <DateOfBirth>1957-03-25</DateOfBirth> 
     </MasterInfo> 
    </MembershipInfoListItem> 
    <Header> 
    <BusinessPartner>CHILIS_US</BusinessPartner> 
    <FileType>mde</FileType> 
    <FileNumber>17</FileNumber> 
    <FormatVariant>1</FormatVariant> 
    <NumberOfRecords>22</NumberOfRecords> 
    <CreationDate>2016-06-07T12:00:46-07:00</CreationDate> 
    </Header> 
     <MembershipInfoListItem> 
     <MembershipIdentifier>PB00000000001956044</MembershipIdentifier> 
     <ParticipationStatus>1</ParticipationStatus> 
     <DataSharing>1</DataSharing> 
     <MasterInfo> 
      <Gender>1</Gender> 
      <Salutation>1</Salutation> 
      <FirstName>Hazel</FirstName> 
      <LastName>Sweetman</LastName> 
      <DateOfBirth>1957-03-25</DateOfBirth> 
     </MasterInfo> 
    </MembershipInfoListItem> 
..... 
..... 
</MemberDataExport> 

私はこのようなファイルを作成したい。..

<MemberDataExport xmlns="http://www.payback.net/lmsglobal/batch/memberdataexport" xmlns:types="http://www.payback.net/lmsglobal/xsd/v1/types"> 
     <MembershipInfoListItem> 
      <MembershipIdentifier>PB00000000001956044</MembershipIdentifier> 
      <ParticipationStatus>1</ParticipationStatus> 
      <DataSharing>1</DataSharing> 
      <MasterInfo> 
       <Gender>1</Gender> 
       <Salutation>1</Salutation> 
       <FirstName>Hazel</FirstName> 
       <LastName>Sweetman</LastName> 
       <DateOfBirth>1957-03-25</DateOfBirth> 
      </MasterInfo> 
     </MembershipInfoListItem> 
</MemberDataExport> 

私はこれを行うことができ、他の方法がありますメモリエラーを起こすことなく? plsもそれを示唆しています。

+0

また、あなたは試してみましたJavaコードを表示することができますか? – JammuPapa

+0

SAXパーサーを使用して最初の要素を取得し、XSL変換 –

答えて

0
あなたがコピーしたい ElementTree.iterparseを使用して、要素(複数可)を発見したとき、その後の解析を破ることができます(Javaのほかに言及した)Pythonで

:より良い名前空間接頭辞の保全については

import xml.etree.ElementTree as ET 
count = 0 
copy = 1 # set this to the number of second level (i.e. children of the root) elements you want to copy 
level = -1 

for event, elem in ET.iterparse('input1.xml', events = ('start', 'end')): 
    if event == 'start': 
     level = level + 1 
     if level == 0: 
      result = ET.ElementTree(ET.Element(elem.tag)) 

    if event == 'end': 
     level = level - 1 
     if level == 0: 
      count = count + 1 
      if count <= copy: 
       result.getroot().append(elem) 
      else: 
       break 



result.write('result1.xml', 'UTF-8', True, 'http://www.payback.net/lmsglobal/batch/memberdataexport') 

を、Iイベントstart-nsを使用して、いくつかの成功を収めたとElementTree上で収集した名前空間を登録しています

import xml.etree.ElementTree as ET 
count = 0 
copy = 1 # set this to the number of second level (i.e. children of the root) elements you want to copy 
level = -1 

for event, elem in ET.iterparse('input1.xml', events = ('start', 'end', 'start-ns')): 
    if event == 'start': 
     level = level + 1 
     if level == 0: 
      result = ET.ElementTree(ET.Element(elem.tag)) 

    if event == 'end': 
     level = level - 1 
     if level == 0: 
      count = count + 1 
      if count <= copy: 
       result.getroot().append(elem) 
      else: 
       break 

    if event == 'start-ns': 
     ET.register_namespace(elem[0], elem[1]) 


result.write('result1.xml', 'UTF-8', True) 
+0

を押します。このコードはうまくいきますが、xmlにxmlns:h = "http://www.w3.org/TR/html4/ "大きなファイルでは、生成されたファイルには次のような内容が含まれています。xmlns:ns0 =" http://www.w3.org/TR/html4/ "。しかし、私は元の接頭辞だけを必要とします。 – mariz

+0

名前空間は 'iterparse'によって' start-ns'と 'end-ns'という別々のイベントとして報告されているようですが、' elem'は '(prefix、namespaceURI) 'のタプルですが、コピーする方法は見つけられません'end'イベントで読み込まれた要素に、または' write'メソッドで直列化がそれらの名前空間を使用することを確認する方法について説明します。 –

+0

@mariz、私は 'start-ns'イベントを収集し、それらを' ElementTree'に登録する2番目のサンプルで答えを編集しました。これは、 'write'呼び出しで行われたシリアライゼーションが少なくともここでPython 3.4で。 –

0

あなたはコードを表示していないため、あなたが何を正しくやっているのか分からないでしょう。しかし、構文解析がOKか、欠落していないかどうかを確認するために、パーサーがファイル全体をロードする必要があり、確かに10 GBファイルのOutOfMemoryエラーが発生する可能性があります。
ので、はちょうどこの場合には、私のアプローチはBufferedStreamReaderHow to read a large text file line by line using Java?を参照)、あなたは終了タグを含む行に到達したときだけ、すなわち</MembershipInfoListItem>、停止使用して行毎にファイルを読み込むために、次のようになります。

StringBuilder sb = new StringBuilder("<MemberDataExport xmlns=\"http://www.payback.net/lmsglobal/batch/memberdataexport\" xmlns:types=\"http://www.payback.net/lmsglobal/xsd/v1/types\">"); 
sb.append(System.lineSeparator()); 
try (BufferedReader br = new BufferedReader(new FileReader(file))) { 
    String line; 
    while ((line = br.readLine()) != null) { 
     // process the line 
     sb.append(line); 
     sb.append(System.lineSeparator()); 
     if (line.contains("</MembershipInfoListItem>")) { 
      break; 
     } 
    } 
    sb.append("</MemberDataExport>"); 
} catch (IOException | AnyOtherExceptionNeeded ex) { 
    // log or rethrow 
} 

今すぐsb.toString()が返されます。

関連する問題