2014-01-30 4 views
1

TREC format에 7GB XML 문서가 있습니다. 이 파일에는 DOC이라는 태그가 있으며 여기에는 DOCNOTEXT이 있습니다.ID 목록을 기반으로 XML 문서 필터링

<FILE> 
<DOC> 
<DOCNO>abc</DOCNO> 
<TEXT>content 
of first 
doc</TEXT> 
</DOC> 
<DOC> 
<DOCNO>def</DOCNO> 
<TEXT>content 
of second 
doc</TEXT> 
</DOC> 
<DOC> 
<DOCNO>ghi</DOCNO> 
<TEXT>content 
of third 
doc</TEXT> 
</DOC> 
</FILE> 

나는이 문서를 필터링 할 및 DOC이의 ID의 목록이 포함 된 파일DOCNO 유지 :

abc 
ghi 

그래서 출력이

<FILE> 
<DOC> 
<DOCNO>abc</DOCNO> 
<TEXT>content 
of first 
doc</TEXT> 
</DOC> 
<DOC> 
<DOCNO>ghi</DOCNO> 
<TEXT>content of 
third 
doc</TEXT> 
</DOC> 
</FILE> 
됩니다를

내 생각에 xml_grep이 유용 할 것입니다. , 그러나 나는 그것을 할 수 없었다.

+0

'XMLStarlet'을 사용하여'DOC' 요소를 얻고,'awk'를 검사하여 pri로 시도해 볼 수 있습니다 'DOCNO'가'abc, ghi'와 같은 요소 만 있습니다. 그것을 시도 했습니까, 아니면 bash에서 필요합니까? – tftd

+0

Thanks @tftd. 나는 단지 id의 목록이 파일에 있음을 강조하고 싶다. 그들 중 4 백만 명이 있습니다. – mossaab

+0

'DOCNO' 콘텐츠를 가져 와서 파일에 저장하고 싶거나'DOCNO'에 특정 문자열이 들어있는'DOC' 요소를 모두 가져오고 싶습니까? 파일 길이와 관련해서는 많은 양의 데이터가 필요합니다. 시스템에 따라 모든 것을 구문 분석하고 저장하는 데 시간이 걸릴 수 있습니다. – tftd

답변

3

xml_grep이있는 경우 모듈 XML::Twig도 설치되어 있다고 가정합니다. 내가 어떻게 xml_grep 일을 모르지만 당신처럼 완전한 스크립트로 동일한 결과를 얻을 수 있습니다 : 그것은 모든 <DOC> 요소를 검색

#!/usr/bin/env perl 

use warnings; 
use strict; 
use XML::Twig; 

XML::Twig->new(
    twig_print_outside_roots => 1, 
    twig_roots => { 
     'DOC' => sub { 
      my $docno = $_->next_elt('DOCNO') || next; 
      if ($docno->text_only =~ m/\A(?:abc|ghi)\Z/) { 
       $_->print; 
      } 
     }, 
    }, 
    pretty_print => 'indented', 
)->parsefile(shift); 

, 다음 중 하나를 읽고 그 텍스트를 추출, 그 abc 또는 비교된다 ghi 정규식을 사용하고 일치하는 부분 트리 만 인쇄합니다.

실행이 같은 :

perl script.pl xmlfile 

그 (그들은 모든 요소에서 있기 때문에 의미가 없습니다 참고 공간) 수율 :

<FILE> 

    <DOC> 
    <DOCNO>abc</DOCNO> 
    <TEXT>content 
of first 
doc</TEXT> 
    </DOC> 


    <DOC> 
    <DOCNO>ghi</DOCNO> 
    <TEXT>content 
of third 
doc</TEXT> 
    </DOC> 
</FILE> 
+0

Birei에게 감사드립니다. 나는 XML :: Twig를 가지고 있지만, id의 목록이 파일에 있다는 것을 강조하고 싶다. 그들 중 4 백만 명이 있습니다. – mossaab

+2

@mossaab : 그 문제를 바꾸는 것은 간단합니다. 파일을 열고 줄 단위로 읽고 각 단어를 해시 키로 저장하십시오. 다음과 같이 해시 검사를 사용하여 정규 표현식 비교를 변경하십시오.'if (exists $ word {$ docno-> text_only}) {...}' – Birei

2

필터링 할 XPath와 xmlstarlet을 만들 AWK를 사용하여 문서 :

+0

이것은 작동하는 솔루션처럼 보입니다. 그러나'xmlstarlet'은 사용 가능한 12G 메모리를 모두 먹은 다음 중단됩니다. 나는 그것을 처리하기 전에 전체 7G 파일을 읽어야한다고 생각합니다. – mossaab

+1

xpath 표현식도 꽤 괴물입니다. Birei의 대답과 함께가는 것이 더 좋습니다. –

관련 문제