2008-12-10 11 views
18

çok büyük XML belgeleri ayrıştırma (ve biraz daha fazlası)(Aşağıdakilerden tüm Java yazılacak olan) java

Ben potansiyel vardır girdi XML belgeleri gibi alacak bir uygulama oluşturmak zorunda çok büyük. Belge şifrelenir - XMLsec ile değil, ancak müşterimin önyükleyici şifreleme algoritması ile - üç aşamada işlenir: İlk olarak, söz konusu algoritmaya göre akış şifresi çözülür.

İkincisi, (ı sağlayan am bir API üçüncü bir şahıs tarafından yazılmış) bir uzantısı sınıf dosyasının bir kısmını okuyacaktır. Okunan miktar öngörülebilir değildir - özellikle dosyanın başlığında olduğu garanti edilmez, ancak XML'in herhangi bir noktasında ortaya çıkabilir.

Son olarak, başka bir uzantı sınıfı (aynı anlaşma) 1..n alt kümesi belgeleri içine girdi XML alt bölümlere edecektir. Bunların, kısmen, ikinci işlemle ele alınan belgenin bir kısmı ile çakışması mümkündür, yani: Bu nesne ile başa çıkmak için kullandığım herhangi bir mekanizmayı geri almam gerektiğine inanıyorum.

hiç bir kerede belleğe veri eserin tümünü okumadan bunu yapmanın bir yolu var mı: İşte

sorum şu? Açıkçası, şifre çözme işlemini bir giriş akışı filtresi olarak uygulayabilirim ancak XML'i tanımladığım şekilde ayrıştırmanın mümkün olup olmadığından emin değilim; Dokümanın çoğunun üzerinde yürürlüğe girmesi, ikinci adımın bilgisini toplamak ve ardından belgeyi geri sarmak ve tekrar işin içine bölmek için tekrar geçerek, belgenin artık kullanılmayan tüm bölümlerini ideal olarak serbest bırakmaktır. Geçtiler.

cevap

12

Stax doğru yoldur. Ben dosyadaki bayt çözer InputStream özel olarak uygulanması yazmak ve daha sonra dere kapalı geliyor gibi çıkan XML Ayrıştırma SAX kullanacağı Woodstox

3

Çok büyük bir arabellek boyutu olan BufferedInputStream ve uzantı sınıfı önce mark() ve reset() kullanın.

uzatma sınıf dosyası içine çok uzaktır ihtiyacı parçalar, daha sonra bu son derece bellek yoğun hale gelebilir Eğer

, 'olsa.

Daha genel bir çözüm kendi BufferedInputStream'u yazmanızdır; bu durumda, arabelleğe alınacak veriler, önceden ayarlanmış bazı eşikleri aşarsa diske gider.

1

Sen XOM tarafından ilginizi çekebilir:

XOM bir ikili akış/ağaç tabanlı API olması ile oldukça benzersizdir. Ağaçtaki tek tek düğümler, belge hala yapılıyorken işlenen olabilir. XOM'un programlarının altta yatan ayrıştırıcı veriyi neredeyse kadar hızlı çalışmasını sağlar. , belgesini, ile çalışmaya başlamadan önce tamamen ayrıştırmanız için beklemeniz gerekmez.

XOM bellek açısından çok verimlidir. Tüm belgeyi belleğe yazdıysanız, XOM mümkün olduğunca az bellek kullanır. Daha da önemlisi, XOM onlar inşa konum olarak filtre belgelere izin verir, böylece size ilgilenmiyor ağacı parçalarını inşa etmek gerekmez . Örneğin, bina metni böyle beyaz boşluk uygulamanızda önemli değilse sadece, sınır boşluk temsil düğümleri atlayabilirsiniz. Hatta parça bir belge parça işlemek ve onunla bitince her parçayı atabilirsin. XOM boyutunda gigabayt olan belgeleri işlemek için kullanılan olmuştur.

+1

Bu ilginç ve potansiyel olarak kullanışlı bir yaklaşım gibi görünüyor, ancak hiçbir yerde dokümantasyonda hiçbir yerde açıklamayacağınız şekilde belgesinin ayrıştırılmasını kontrol etmenin bir yolu var. Ben size _can_ inanıyorum ama yeteneği keşfetmek için makul bir şekilde belgelenmez. –

7

Bu, StAX (JSR 173) için bir iş gibi görünüyor. StAX, SAX gibi bir olaya dayalı ayrıştırıcı gibi daha çok veya daha az çalıştığı anlamına gelen bir çekme ayrıştırıcısıdır, ancak, ne zaman, hangi öğeleri çekeceğini, daha fazla denetim sahibi olduğunuz anlamına gelir, ...

Eğer vb bunların uygulanması, üzerinde kontrol sahibi olmadığını çözüm

ana maddeden oluşan belgede çok büyükse, muhtemelen bir temel olay kullanmak istediğiniz olmasıdır ..., Uzantınızın sınıfları aslında ne yaptığını çok bağlı olacaktır ayrıştırıcı ve ağaç tabanlı değil, bu yüzden çok fazla bellek kullanmazsınız.

StAX uygulamaları SUN (SJSXP), Codehaus veya diğer birkaç sağlayıcıdan bulunabilir.

+0

Bu, verimli bir şekilde takılabildiğim sürece umut verici görünüyor. Görünüşe göre, StAX'ı API'mın istemcilerine sunmam gerekecek, ki bu da idealin altında değil, ama en azından yetenekler var gibi görünüyor. Gönderinizi liste yerine önerilen bir uygulama ile değiştirebilir misiniz? –

+1

Bu eski bir cevap/yorum olduğunu biliyorum, ancak StaxMate [http://staxmate.codehaus.org/Tutorial] gibi, stax üstüne biraz daha fazla rahatlık ekleyebilir ve (bazı alt düzey ayrıntıları izole) bazı libs vardır ]. Bu, artımlı ayrıştırma/yazma işlemine izin verir, ancak yazılacak kod miktarını azaltır. – StaxMan

3

bakarak öneriyoruz.

SAXParserFactory.newInstance().newSAXParser().parse(
    new DecryptingInputStream(), 
    new MyHandler() 
); 
0

XOM kitaplığına bakın. Aradığınız örnek, kaynak dağıtımının örnek dizininde StreamingExampleExtractor.java dur. Bu, yalnızca belirli düğümleri oluşturmak, bunları işlemek ve atmak için büyük bir xml belgesinin akış ayrıştırması gerçekleştirme tekniğini gösterir. Bu bir sax yaklaşımına çok benzer, fakat çok daha fazla ayrıştırma kabiliyetine sahiptir, böylece bir akış ayrıştırması oldukça kolay bir şekilde gerçekleştirilebilir.

Eğer NUX daha yüksek seviyede bakışta çalışmak istiyorsanız

. Bu, yalnızca xpath değerini değerlendirmek için gereken belleğe veri miktarını okuyan yüksek düzeyde bir akışlı xpath API'si sağlar.