2009-10-02 13 views
5

Yapısal biçimlendirme verilerinin büyük bir dosyasını (> 5GB) ayrıştırmaya çalışıyorum. Veri formatı esasen XML'dir ancak açık bir kök öğesi yoktur. Bunu yapmanın en etkili yolu nedir?Python'da büyük sözde xml dosyalarını ayrıştırma

SAX ayrıştırıcılarıyla ilgili sorun, bir kök öğesi gerektirmesidir, bu nedenle ya veri akışına sahte bir öğe ekleyelim (Java'nın Python'da SequenceInputStream öğesine eşdeğer var mıdır?) Ya da SAX olmayan bir olaya dayalı çözümleyici (sgmllib'in bir varisi var mı?)

Verilerin yapısı oldukça basittir. elementlerin Temelde bir liste:

<Document> 
    <docid>1</docid> 
    <text>foo</text> 
</Document> 
<Document> 
    <docid>2</docid> 
    <text>bar</text> 
</Document> 

* aslında xml.sax.parse bir 'akış' nesne geçirebilmesi,

cevap

11

http://docs.python.org/library/xml.sax.html

Not yineleme için. Bu, muhtemelen parse çağrısına dosya benzeri yöntemler (read gibi) içeren herhangi bir nesneyi geçirebileceğiniz anlamına gelir. Öncelikle sanal kök başlangıç ​​etiketinizi, daha sonra dosya içeriğini ve sonra sanal kökünü yazacak kendi nesnesini yaratın sonuna etiketi. Sanırım sadece read yöntemini uygulamanız gerekiyor ... ama bu kullanacağınız sax ayrıştırıcısına bağlı olabilir. benim için çalışıyor

Örnek:

import xml.sax 
import xml.sax.handler 

class PseudoStream(object): 
    def read_iterator(self): 
     yield '<foo>' 
     yield '<bar>' 
     for line in open('test.xml'): 
      yield line 
     yield '</bar>' 
     yield '</foo>' 

    def __init__(self): 
     self.ri = self.read_iterator() 

    def read(self, *foo): 
     try: 
      return self.ri.next() 
     except StopIteration: 
      return '' 

class SAXHandler(xml.sax.handler.ContentHandler): 
    def startElement(self, name, attrs): 
     print name, attrs 

d = xml.sax.parse(PseudoStream(), SAXHandler()) 
+0

mi? Bu kodun bir müşterisi, sadece 'read()' yi kullandıysa EOF'u nasıl fark ederdi? –

+4

Python'daki akış benzeri nesnelerin özelliklerinden biri, bir read() çağrısının en az bir baytı engelleyip döndürdüğü veya EOF olması durumunda boş dizge döndürdüğüdür. Orijinal dosya.read yöntemi böyle çalışır. – liori

+1

Bunu PullDOM ile birlikte kullanmak isteyebilirsiniz - SAX'in akış doğasını DOM'ın hiyerarşik yapısıyla birleştirir. – RichieHindle

1

hızlı ve kirli cevap (String) bir kök öğesi ekleyerek olacağını bu nedenle geçerli bir XML olacaktır.

Saygılarımızla.

1

Ekleme kök öğesi ve SAX, StAX veya VTD-XML kullanabilirsiniz ..

+0

Bay Zhang - iyi cevap. Ben onu reddettim. –

+0

Meta hesabı buna bağladım, söz verdiğiniz 100 nokta nerede? –

0

xml.parsers.expat - Expat xml.parsers.expat modülü kullanarak Hızlı XML ayrıştırma Expat olmayan bir Python arayüzü -sürümü ayrıştırıcı XML. Modül, bir XML ayrıştırıcısının mevcut durumunu temsil eden tek bir uzantı türü olan xmlparser sağlar. Bir xmlparser nesnesi oluşturulduktan sonra, nesnenin çeşitli öznitelikleri işleyici işlevlerine ayarlanabilir. Bir XML belgesi daha sonra ayrıştırıcıya beslendiğinde, XML belgesindeki karakter verileri ve işaretleme için işleyici işlevleri çağrılır.

diğer bilgiler: gerçekten doğru olanı StopIteration` `yapmak için` `dönüş 'http://www.python.org/doc/2.5/lib/module-xml.parsers.expat.html