Szybkie dzielenie dużych plików XML za pomocą bezpiecznego skryptu Pythona

Aby szybko podzielić duży plik XML, należy podzielić go na całe, powtarzające się rekordy, zamiast wycinać z pliku bajty. Poniższy przykład wykorzystuje standardową bibliotekę Pythona do strumieniowego przesyłania danych wejściowych i zapisywania oddzielnych dokumentów XML z tym samym elementem głównym i atrybutami głównymi. Jest to przeznaczone dla typowej struktury, takiej jak <records><record>...</record><record>...</record></records>, gdzie każdy bezpośredni element potomny elementu głównego jest niezależnym rekordem.

Edytor XML pokazuje katalog główny rekordu z powtarzającymi się elementami rekordu i powiększony rekord zawierający identyfikator, nazwę i wartość elementów podrzędnych.
Podział następuje w miejscu powtarzających się rekordów podrzędnych bezpośrednio pod korzeniem; dowolne granice bajtów mogą spowodować uszkodzenie znacznika XML.

Wybierz bezpieczny punkt podziału

Dokument XML ma jeden element dokumentu, a jego znaczniki muszą być poprawnie zagnieżdżone. Moduł rozdzielający pliki RAW może przeciąć znacznik początkowy, zagnieżdżony rekord, a nawet sekwencję kodowania znaków, pozostawiając fragmenty, które nie są samodzielnym dokumentem XML. Specyfikacja W3C XML wyjaśnia zasady poprawnego formatowania dokumentu i elementu głównego.

Przed podziałem sprawdź plik i zidentyfikuj powtarzający się element rekordu. Ten skrypt traktuje każdy bezpośredni element podrzędny pod elementem głównym jako jedną całość. Używaj go tylko wtedy, gdy te elementy podrzędne są niezależnymi rekordami, a sam element główny nie zawiera znaczącego tekstu mieszanego ani metadanych, które muszą znajdować się w określonym miejscu. Jeśli rekordy są zagnieżdżone kilka poziomów niżej, użyj dzielnika zaprojektowanego dla tego słownika XML, zamiast bezmyślnie zmieniać skrypt.

Co ze Split That XML / OOXP Splitter?

Oryginalny artykuł wskazywał czytelnikom Split That XML. Strona projektu SourceForge nadal opisuje to narzędzie, ale ostatnia aktualizacja została podana na 27 września 2015 roku. Traktuj je jak przestarzałe oprogramowanie: stare oświadczenie o zgodności z systemem Windows nie potwierdza obsługi na obecnych systemach. Jeśli posiadasz już kopię, pracuj nad duplikatem pliku i sprawdź poprawność wyników przed ich użyciem.

Dzielenie rekordów za pomocą Pythona

Python xml.etree.ElementTree.iterparse()odczytuje dokument przyrostowo, co pozwala uniknąć ładowania całego drzewa XML do pamięci naraz. Poniższy skrypt grupuje elementy podrzędne w partie, a następnie zapisuje każdą partię w nowej kopii oryginalnego znacznika głównego i atrybutów. Nie wymaga on żadnych zewnętrznych pakietów. Jeśli Python nie jest zainstalowany, należy skorzystać z oficjalnych plików do pobrania Python dla systemu Windows ; dokumentacja ElementTree opisuje użyty tutaj parser.

Folder roboczy zawiera pliki input.xml i split_xml.py, a kod źródłowy XML jest otwarty w edytorze tekstu.
Zachowaj oryginał w stanie nienaruszonym i dla każdego przebiegu wybierz nowy, pusty folder wyjściowy.
  1. Utwórz kopię roboczą źródłowego pliku XML. Utwórz nowy, pusty folder wyjściowy, taki jak parts.
  2. W edytorze zwykłego tekstu zapisz poniższy kod split_xml.pyw tym samym folderze roboczym, w którym znajduje się kopia.
from pathlib import Path
import sys
import xml.etree.ElementTree as ET

source = Path(sys.argv[1])
out_dir = Path(sys.argv[2])
records_per_file = int(sys.argv[3]) if len(sys.argv) > 3 else 500

if records_per_file < 1:
    raise SystemExit("records_per_file must be at least 1")
out_dir.mkdir(parents=True, exist_ok=True)
if any(out_dir.glob("part_*.xml")):
    raise SystemExit("Choose a new, empty output folder first")

records = []
part_count = 0
root = None
root_tag = None
root_attrib = {}

def write_part(items, number):
    wrapper = ET.Element(root_tag, root_attrib)
    wrapper.extend(items)
    target = out_dir / f"part_{number:04d}.xml"
    ET.ElementTree(wrapper).write(
        target, encoding="utf-8", xml_declaration=True
    )

depth = 0
for event, elem in ET.iterparse(source, events=("start", "end")):
    if event == "start":
        depth += 1
        if depth == 1:
            root = elem
            root_tag = elem.tag
            root_attrib = dict(elem.attrib)
    else:
        if depth == 2:
            records.append(elem)
            if len(records) == records_per_file:
                part_count += 1
                write_part(records, part_count)
                records.clear()
                root[:] = []
        depth -= 1

if records:
    part_count += 1
    write_part(records, part_count)
if part_count == 0:
    raise SystemExit("No direct-child elements were found under the root")
print(f"Wrote {part_count} files.")

Uruchom polecenie

Otwórz program PowerShell w folderze roboczym i sprawdź, czy Python jest dostępny. Ostatnim argumentem jest liczba rekordów w każdej części; domyślna wartość to 500, jeśli ją pominiesz.

python --version
python split_xml.py input.xml parts 500

W instalacji systemu Windows z programem uruchamiającym Pythona, drugi wiersz może wyglądać następująco py -3 split_xml.py input.xml parts 500: . Skrypt zapisuje pliki takie jak part_0001.xmli raportuje ich liczbę. Za każdym razem należy używać pustego folderu wyjściowego; skrypt zatrzymuje się, jeśli pasujące pliki części już się tam znajdują, więc nie będzie automatycznie mieszać nowego uruchomienia z resztkami.

W oknie programu Windows PowerShell wyświetlane jest polecenie podziału pliku input.xml na części zawierające po 500 rekordów każda.
Trzeci argument polecenia ustawia liczbę rekordów, a nie gwarantowany maksymalny rozmiar pliku.

Sprawdź wyniki przed importem

Najpierw przeanalizuj każdą wygenerowaną część, aby wychwycić błędny kod XML. W programie PowerShell uruchom:

python -c "import glob, xml.etree.ElementTree as ET; files=glob.glob('parts/*.xml'); [ET.parse(p) for p in files]; print(f'{len(files)} files parsed')"

Upewnij się, że zgłoszona liczba nie jest równa zero, sprawdź kilka plików i porównaj całkowitą liczbę rekordów ze źródłem. Pomyślna analiza składniowa dowodzi jedynie, że część jest poprawnie sformatowana . Nie dowodzi natomiast, że spełnia ona schemat XML (XSD), DTD, regułę biznesową ani wymagania aplikacji, która będzie ją wykorzystywać. W razie potrzeby zweryfikuj każdą część zgodnie ze schematem lub walidatorem używanym przez system docelowy. Zasoby W3C dotyczące schematu XML wyjaśniają odrębną rolę ograniczeń schematu.

W folderze części znajduje się lista trzech plików części XML umieszczona nad wierszem poleceń, służącym do sprawdzania wyników.
Przeanalizuj każdą część pod kątem poprawności strukturalnej, a następnie osobno uruchom sprawdzanie schematu lub importu aplikacji.

Ograniczenia i szybkie rozwiązania

  • Część jest nadal za duża: zmniejsz liczbę rekordów, np. z 500 do 100. Pojedynczy duży rekord nadal może spowodować, że jedna z części przekroczy rozmiar docelowy; ten skrypt nie narzuca sztywnego limitu megabajtów.
  • Części nie przechodzą walidacji schematu: sprawdź, czy wybrana granica rekordu jest zgodna z wymaganą strukturą i kolejnością w schemacie. Podział może zachować poprawne zagnieżdżenie bez naruszania poprawności na poziomie dokumentu.
  • Zmieniono prefiksy lub formatowanie: ElementTree może serializować prefiksy przestrzeni nazw w inny sposób i normalizuje reprezentację XML. Porównywanie sparsowanych wartości i zachowania aplikacji zamiast oczekiwania na kopiowanie bajt po bajcie.
  • Źródło używa DTD, komentarzy, instrukcji przetwarzania lub metadanych na poziomie głównym: ten prosty skrypt nie zachowuje wszystkich konstrukcji na poziomie dokumentu. Zamiast tego użyj narzędzia XML obsługującego słownictwo i przetestuj na kopii.

W przypadku standardowej listy niezależnych rekordów, takie podejście zapewnia łatwe w zarządzaniu, oddzielnie parsowalne pliki bez naruszania znaczników nadrzędny-podrzędny. Struktura rekordu i reguły walidacji w miejscu docelowym decydują o tym, czy wynikowe części są również prawidłowe dla danego przepływu pracy.

Zostaw komentarz

Konwertuj zdjęcia na obrazy, szkice i kreskówki za pomocą FotoSketcher

Konwertuj zdjęcia na obrazy, szkice i kreskówki za pomocą FotoSketcher

Zamień zdjęcie w obraz, szkic ołówkiem lub komiks dzięki FotoSketcher Studio. Dowiedz się, jak wybrać efekt, dostosować podgląd i zapisać swoją grafikę.

Szczegółowa analiza i identyfikacja plików audio dzięki Audio Identifier

Szczegółowa analiza i identyfikacja plików audio dzięki Audio Identifier

Dowiedz się, co Audio Identifier ujawnia na temat szybkości transmisji, koderów i tagów, jak działa jego starszy proces pracy i które obecne narzędzia sprawdzają pliki lub identyfikują utwory.

Mój indeks zdjęć: program do organizacji zdjęć typu open source dla systemu Windows

Mój indeks zdjęć: program do organizacji zdjęć typu open source dla systemu Windows

My Photo Index to starszy katalog zdjęć dla systemu Windows, umożliwiający tagowanie, ocenianie i przeglądanie lokalnych obrazów. Zapoznaj się z udokumentowanymi funkcjami, ograniczeniami zgodności i aktualizowaną alternatywą.

Zmień atrybuty plików i folderów, daty i godziny za pomocą narzędzia Attribute Changer

Zmień atrybuty plików i folderów, daty i godziny za pomocą narzędzia Attribute Changer

Dowiedz się, jak używać narzędzia Attribute Changer do edytowania atrybutów plików systemu Windows i znaczników czasu, aktualizowania dat zdjęć JPEG EXIF ​​i bezpiecznego podglądu zmian wsadowych.

Jak ustawić inną tapetę na każdym monitorze w systemie Windows 10

Jak ustawić inną tapetę na każdym monitorze w systemie Windows 10

Ustaw osobną tapetę dla każdego monitora systemu Windows 10, zidentyfikuj wyświetlacze, dostosuj dopasowanie obrazu i rozwiąż problemy z brakującymi opcjami monitora.

pViewer: Minimalistyczna przeglądarka obrazów i czytnik mangi i komiksów

pViewer: Minimalistyczna przeglądarka obrazów i czytnik mangi i komiksów

Dowiedz się, do czego służy pViewer, jak działają tryby zdjęć i komiksów, którą edycję systemu Windows pobrać i czym różnią się wersje starsza i przepisana.

NeoDownloader: ustawianie parametrów i zbiorcze pobieranie obrazów ze stron internetowych

NeoDownloader: ustawianie parametrów i zbiorcze pobieranie obrazów ze stron internetowych

Dowiedz się, jak utworzyć projekt NeoDownloader, wybrać zakres indeksowania, ustawić filtry obrazów i miejsce docelowe oraz przeglądać pliki do pobrania w partiach.

Jak przełączyć się na następną tapetę pulpitu za pomocą klawisza skrótu w systemach Windows 7 i 8

Jak przełączyć się na następną tapetę pulpitu za pomocą klawisza skrótu w systemach Windows 7 i 8

Skonfiguruj pokaz slajdów w systemie Windows 7 lub 8, utwórz krótki skrót VBScript i przypisz klawisz skrótu, aby przejść do następnej tapety.

XnConvert: stosuj efekty i konwertuj formaty obrazów partiami

XnConvert: stosuj efekty i konwertuj formaty obrazów partiami

Użyj XnConvert do stosowania efektów, zmiany rozmiaru zdjęć i konwersji formatów obrazów w partiach. Wybierz ustawienia wyjściowe, wyświetl podgląd edycji i chroń swoje oryginały.

PickMeApp: Przenieś programy Windows z zapisanymi ustawieniami

PickMeApp: Przenieś programy Windows z zapisanymi ustawieniami

Przenieś zainstalowane aplikacje systemu Windows na inny komputer za pomocą aplikacji PickMeApp. Dowiedz się, jak działają pakiety TAP, jak przechwycić ustawienia i co może nie zostać przeniesione.