2011-10-12 16 views
6

Mam następujący problem: Mam bardzo duże pliki XML (np. 300+ Megs) i muszę je przeanalizować, aby dodać niektóre z ich wartości do bazy danych. Struktura tych plików jest również bardzo złożona. Chcę użyć Stax Parser, ponieważ oferuje on ładną możliwość parsowania (i przetwarzania w ten sposób) tylko części pliku XML naraz, a więc nie wczytywania całej zawartości do pamięci, ale z drugiej strony uzyskiwania wartości za pomocą Stax (przynajmniej na tych plikach XML) jest kłopotliwy, muszę napisać tonę kodu. Z tego ostatniego punktu widzenia niezmiernie mi pomoże, gdybym mógł ustawić plik XML na obiektach Javy (jak robi to JAX-B), jednak to ładowałoby cały plik plus tony instancji Object w pamięci naraz.Parsowanie bardzo dużych plików XML i rozesłanie do obiektów Java

Moje pytanie brzmi, czy istnieje sposób, aby wykonać ciągły proces (lub po prostu częściowo przeanalizować) plik sekwencyjnie, a następnie przesłać tylko te części do obiektów Java, aby móc sobie z nimi poradzić bez zbędnego obciążania pamięci?

Odpowiedz

2

Cóż, najpierw off Ja wanna podziękować dwie osoby odpowiadając na moje pytania, ale ostatecznie skończyło się na nie za pomocą tych twierdzeń częściowo dlatego, że te proponowane technologie są trochę daleko od Java niech powiedzmy "standardowe przetwarzanie XML" i dziwne jest, że dzieje się tak, gdy istnieje podobne narzędzie już obecne w Javie, a częściowo także dlatego, że znalazłem rozwiązanie, które wykorzystuje tylko API Java, aby to osiągnąć.

Nie będę szczegółowo opisywał rozwiązania, które znalazłem, ponieważ już skończyłem implementację i jest to całkiem spora część kodu do umieszczenia tutaj (używam Spring Batch na górze wszystkiego, z toną konfiguracja i inne).

będę jednak zrobić mały komentarz na temat tego, co ostatecznie skończyło się robi:

Big Idea jest fakt, że jeśli dokument XML i to odpowiada schematu XSD, można analizować & Marshall to z JAXB i możesz to zrobić w porcjach, a fragmenty można odczytać za pomocą równego parsera, takiego jak STAX, a następnie przekazać do JAXB Marshaller.

To praktycznie oznacza, że ​​najpierw musisz zdecydować, gdzie jest dobre miejsce w twoim pliku XML, gdzie możesz powiedzieć "ta część ma dużo powtarzalnej struktury, potraktuję te powtórzenia pojedynczo". Te powtarzające się części są zazwyczaj tym samym (dzieckiem) znacznikiem powtórzonym w tagu nadrzędnym. Więc wszystko, co musisz zrobić, to zrobić detektor zdarzeń w twoim parserze STAX, który jest uruchamiany na początku każdego z tych tagów podrzędnych, a następnie przesłać do JAXB zawartość tego znacznika potomnego, połączyć go z JAXB i przetworzyć.

Naprawdę pomysł jest doskonale opisany w tym artykule, który śledziłem (prawda, pochodzi z 2006 roku, ale dotyczy JDK 1.6, który w tamtym czasie był całkiem nowy, więc pod względem wersji wcale nie jest taki stary):

http://www.javarants.com/2006/04/30/simple-and-efficient-xml-parsing-using-jaxb-2-0/

+0

Dobrze wiedzieć, że twój problem został rozwiązany. Zastanawiasz się, jak to jest (soln w tym poście) inne od tego, co napisałem? – Kashyap

+0

Cóż, szczerze mówiąc, był to strach przed dużymi strukturami, część leniwości :) (obie są złe i godne ubolewania). Po pierwsze, z dokumentacji EMF wydaje się być dość zaangażowaną strukturą, nie tylko dla przetwarzania XML, ale dla mnóstwa innych rzeczy i zawsze staram się unikać tak ciężkich frameworków, kiedy tylko jest to możliwe (to tylko osobiste preferencje, nie jestem powiedzenie jest złe, aby to zrobić w ogóle). Po drugie, jestem leniwy, a EMF używa niestandardowych API parsowania XML, o których nie wiem, dlatego też preferowałem rozwiązanie ze standardowymi API Java XML. –

+1

Rzeczywiście, bez względu na to, czy podoba Ci się EMF, czy nie, zaleciłem NIE używać go ("** ponieważ EMF jest zbyt dużym młotkiem dla tak małego problemu. **"), chyba że nie masz wyboru. I o parserze, aby zacytować ponownie "tak ** po prostu parsuj używając czegokolwiek chcesz **, stwórz trochę StringStream lub coś dla każdego w pętli i ** przejdź do JAX-B lub EMF. **" – Kashyap

5

Polecam Eclipse EMF. Ale ma ten sam problem, jeśli nadasz mu nazwę pliku, który będzie analizował całość. Chociaż istnieje kilka opcji zmniejszenia ilości załadowanych, ale nie przeszkadzało mi to zbytnio, ponieważ pracujemy na komputerach z 96 GB pamięci RAM. :)

W każdym razie, jeśli twój format XML jest dobrze zdefiniowany, jednym z rozwiązań jest oszukanie EMF poprzez podzielenie całego pliku na kilka mniejszych (ale wciąż dobrze zdefiniowanych) fragmentów XML. Następnie podaj każdy z nich jeden po drugim. Nie znam JAX-B, ale być może można zastosować tamto samo obejście. Co polecam, ponieważ EMF to zbyt duży młotek do tak małego problemu.

Wystarczy opracować trochę jeśli XML wygląda następująco:

<tag1> 
    <tag2> 
     <tag3/> 
     <tag4> 
      <tag5/> 
     </tag4> 
     <tag6/> 
     <tag7/> 
    </tag2> 

    <tag2> 
     <tag3/> 
     <tag4> 
      <tag5/> 
     </tag4> 
     <tag6/> 
     <tag7/> 
    </tag2> 
............ 
    <tag2> 
     <tag3/> 
     <tag4> 
      <tag5/> 
     </tag4> 
     <tag6/> 
     <tag7/> 
    </tag2> 
</tag1> 

to może być podzielone na jedną XML każdy zaczynając <tag2> a kończąc </tag2>. W Javie większość parserów akceptuje Strumień, więc po prostu parsuj używając czegokolwiek, stwórz StringStream lub coś dla każdego <tag2> w pętli i przejdź do JAX-B lub EMF.

HTH

+0

to jest coś, co brzmi świetnie i że postaram pierwszą rzeczą jutro (to jest północ tu teraz :)). Dzięki za sugestię, dźwięki obiecują –

+1

@thekashyap. Czy mogę mieć jedną z tych maszyn, plesae? Tylko jeden! –

+0

Hehe .. To są nasze maszyny testowe, w domu pracuję na laptopie Win7 z 4GB jak wszyscy inni :) :) – Kashyap

1

Projekcja dokumentu może być tutaj odpowiedzią. Saxon i wiele innych procesorów XQuery oferuje to jako opcję. Jeśli masz dość prostą kwerendę, która wybiera małą ilość danych z dużego dokumentu, procesor kwerend analizuje zapytanie, aby ustalić, które części drzewa muszą być dostępne dla zapytania i które mogą zostać odrzucone podczas przetwarzania. Wynikowe drzewo często może być tylko 1% wielkości całego dokumentu. Szczegóły dotyczące Saxon tutaj:

http://saxonica.com/documentation/sourcedocs/projection.xml

Powiązane problemy