2015-05-18 15 views
9

Mam kolekcję plików XML, a niektóre z nich są dość duże (do ~ 50 milionów węzłów elementów). Używam xmllint do sprawdzania poprawności tych plików, co działa całkiem dobrze nawet dla ogromnych dzięki strumieniowemu API.Jak wykonać kwerendę XPath w wierszu polecenia w dużych plikach XML?

xmllint --loaddtd --stream --valid /path/to/huge.xml 

Niedawno dowiedziałem się, że xmllint jest również zdolny do zapytań XPath wiersza poleceń, co jest bardzo wygodne.

xmllint --loaddtd --xpath '/root/a/b/c/text()' /path/to/small.xml 

Jednak te zapytania XPath nie działają dla dużych plików XML. Po pewnym czasie otrzymuję komunikat "Killed". Próbowałem włączyć streaming API, ale to po prostu nie generuje żadnego wyjścia.

xmllint --loaddtd --stream --xpath '/root/a/b/c/text()' /path/to/huge.xml 

Czy istnieje sposób włączenia trybu strumieniowego podczas wykonywania zapytań XPath przy użyciu xmllint? Czy istnieją inne/lepsze sposoby wykonywania zapytań XPath z linii poleceń w przypadku dużych plików XML?

+0

spróbować '--shell' opcję interaktywnej (z tylko ścieżki do pliku XML) – flafoux

+0

próbowałem otwarciu interaktywną powłokę do ogromnego pliku, ale będzie to awarię („Zabity”, podobnie jak w przypadek nie używania '--stream') zanim będę mógł wprowadzić dowolne polecenie. – MRA

+0

http://superuser.com/questions/543881/efficiently-extracting-a-few-data-from-a-large-xml- file –

Odpowiedz

3

Jeśli wyrażenia XPath są bardzo proste, spróbuj xmlcutty.

Od głównej:

xmlcutty jest prostym narzędziem do pominięcia elementów z dużych plików XML, szybko. Ponieważ działa w trybie strumieniowym, prawie nie korzysta z pamięci i może przetwarzać około 1G XML na minutę.

+1

Polecenie takie jak 'xmllint --loaddtd --xpath '/ root/a/b/c/text()'/path/to/small.xml' zostanie przetłumaczone na' xmlcutty -path '/ root/a/b/c '-rename' \ n '/ path/to/small.xml' - gdzie * zmiana nazwy * ma na celu zmianę nazwy ostatniego elementu otaczającego - i tym samym symulowanie 'text()' - składnia jest nieco tajemna. – miku

-1

zmiana ulimits może działać. Spróbuj tego:

$ ulimit -Sv 500000 
$ xmllint (...your command)