XML Diff: porównaj dwa pliki XML online
Wklej, sformatuj i porównaj dwa dokumenty XML obok siebie. Pretty-print, walidacja i podświetlanie świadome namespace'ów wbudowane.
Czym jest narzędzie XML diff?
Darmowe narzędzie w przeglądarce do porównywania dwóch dokumentów XML. Wklej stary pom.xml po lewej, nowy po prawej, a zmiany rozjaśniają się element po elemencie. Nic nie opuszcza Twojego komputera.
Sam diff działa na poziomie znaków, a walidacja przechodzi przez natywny DOMParser przeglądarki. Przycisk Format w każdym panelu układa Twój XML na nowo z konsekwentnym wcięciem. Walidacja na żywo wskazuje źle uformowane znaczniki, niesparowane tagi i zepsute referencje encji w trakcie pisania.
Jeśli kiedyś otwierałeś w code review Spring application context na 4000 linii, szukając jednego beana, którego atrybut class się zmienił, to jest narzędzie, które zaprowadzi Cię tam w sekundy. Dla zwykłej prozy nasze narzędzie do diffu tekstu jest właściwym wyborem. Dla danych strukturalnych z parami klucz/wartość JSON diff radzi sobie z reorganizacją obiektów czyściej, niż potrafi XML.
Jak diff naprawdę działa
Diff działa na poziomie znaków, a następnie semantyczne post-processing przesuwa podświetlenia tak, żeby trafiały na nazwy tagów, atrybuty i treść tekstową, a nie na przypadkowe znaki interpunkcyjne. Wstawienia widać na zielono w panelu po prawej, usunięcia na czerwono po lewej.
XML ma kilka osobliwości, które spec wprost wymienia, i wszystkie kąsają, gdy porównujesz dwa pliki jako tekst. Specyfikacja XML 1.0 mówi, że kolejność atrybutów na elemencie nie jest istotna, więc dla parsera <img src="a.png" alt="x"/> i <img alt="x" src="a.png"/> to to samo. Diff tekstowy mimo to zaznaczy zamianę. Bez porównania strukturalnego nie ma na to lekarstwa; praktyczne obejście to sformatować obie strony tym samym narzędziem, żeby kolejność atrybutów była stabilna.
Namespace'y dokładają kolejną warstwę. Dwa dokumenty wiążące to samo URI z różnymi prefiksami są równoważne według Namespaces in XML 1.0, ale diff tekstowy zamaluje każdą zamianę ns1: na ns2: jako zmianę. Sformatuj obie strony, wyrównaj prefiks w jednej z nich i zrób diff jeszcze raz. Dla pipeline'u, który normalizuje namespace'y i kolejność atrybutów przed diffem, spójrz na XSLT 3.0 albo na krok kanonikalizacji zgodny z Canonical XML.
Jak porównać XML w trzech krokach
Dwa panele tekstowe, jeden diff. Bez rejestracji, bez przesyłania, bez ruchu do serwera.
- 1
Wklej lub wczytaj swój XML
Wklej stary XML po lewej, nowy po prawej. Albo kliknij Wczytaj po dowolnej stronie, żeby wczytać plik .xml, .pom, .config lub .svg bezpośrednio. Przycisk Przykład wypełnia oba panele małym pom.xml, jeśli chcesz najpierw zobaczyć narzędzie w akcji.
- 2
Sformatuj obie strony, żeby porównanie było uczciwe
Kliknij Format w każdym panelu, żeby pretty-print z konsekwentnym wcięciem i łamaniem linii. To normalizuje białe znaki, więc diff podświetla prawdziwe zmiany treści, a nie szum formatu z pliku Windows CRLF kontra plik Unix LF. Plakietka walidacji robi się zielona, gdy DOMParser przyjmuje dokument jako poprawnie uformowany.
- 3
Czytaj diff
Usunięcia pojawiają się z czerwonym podświetleniem po lewej, wstawienia z zielonym po prawej. Przewijaj jedną stronę, druga podąża. Liczniki zmian w każdym nagłówku mówią, ile odrębnych edycji diff znalazł w nazwach elementów, wartościach atrybutów i treści tekstowej.
Kiedy XML diff to właściwe narzędzie
Przegląd aktualizacji zależności w pom.xml
PR od Dependabota podnosi piętnaście koordynat Mavena naraz. Wklej stary pom.xml obok nowego, żeby potwierdzić rzeczywiste aktualizacje: spring-boot-starter-web przeszedł z 3.1.5 na 3.2.1, jackson-databind z 2.15.3 na 2.16.0, i dorzucono nową zależność micrometer-registry-prometheus. Diff sprawia, że skoki wersji są oczywiste, więc możesz skonfrontować je z changelogiem przed zatwierdzeniem.
Diff Spring application context XML
Kiedy serwis zaczyna padać po refaktorze, przyczyną często jest pojedynczy bean, którego atrybut class albo argument konstruktora zmienił się w applicationContext.xml. Wklej działającą rewizję obok HEAD; diff od razu wyciąga zamianę class="com.acme.OldDataSource" na class="com.acme.HikariDataSource", a otaczające tagi <property> mówią, jaka konfiguracja przeszła razem z nim.
Porównywanie ciał żądania i odpowiedzi SOAP
Integracja SOAP, która działała wczoraj, dziś zwraca Fault. Złap obie koperty z loggera pakietów albo nagrań WireMocka, wrzuć do diffu i sprawca wyskakuje: <currencyCode>, który zniknął z USD i przeszedł w brakujący element, albo deklaracja namespace na soap:Envelope, którą upstream cicho zmienił. Bez widoku side-by-side znalezienie tego w 800 liniach XML to walka z wiatrakami.
Audyt uprawnień AndroidManifest.xml
Przed wypuszczeniem release diffuj AndroidManifest.xml wobec poprzedniego taga, żeby wyłapać rozrost uprawnień. Nowe <uses-permission android:name="android.permission.READ_CONTACTS"/>, które wślizgnęło się przy aktualizacji SDK strony trzeciej, to dokładnie to, co Play Store wyłapie podczas review. Diff wyciąga też zmiany w elementach <intent-filter> i flagach android:exported, częstych punktach uwagi w przeglądach bezpieczeństwa.
Śledzenie zmian schematu w feedach RSS lub Atom
Czytnik feedów wywala się, bo źródło przeszło z RSS 2.0 na Atom 1.0, albo wydawca dorzucił nowy namespace <media:thumbnail>. Zapisz snapshot działającego feeda, zdiffuj go z aktualnym, i strukturalna zmiana pojawia się w sekundy. Ten sam flow dla importów OPML i feedów podcastowych, w których metadane na poziomie channela przemieściły się między elementami.
Diffy document.xml z OOXML
.docx to po prostu zip z XML w środku. Rozpakuj obie wersje umowy, puść diff na word/document.xml, i widzisz prawdziwe edycje tekstu bez wchodzącej w drogę adnotacji śledzenia zmian z Worda. Przydatne, gdy paralegal odsyła "czystą" kopię, która rzekomo zgadza się z redline'em; XML mówi, które elementy paragrafów się przesunęły i jakie formatowanie na poziomie run się zmieniło.
Szybka referencja XML
Krótka ściąga z parsingowych przypadków granicznych, które to narzędzie wyciąga najczęściej. Wszystko zakorzenione w specyfikacjach XML W3C.
| Topic | What this tool does |
|---|
| Kolejność atrybutów | Nieistotna według spec XML 1.0. Dla parsera <a x="1" y="2"/> równa się <a y="2" x="1"/>. Diff tekstowy zaznaczy zamianę; sformatuj obie strony, żeby utrzymać stabilną kolejność. |
|---|
| Namespace'y | Wiązane przez URI, aliasowane przez prefiks. Dwa dokumenty wiążące to samo URI z różnymi prefiksami są równoważne. Zobacz Namespaces in XML 1.0. |
|---|
| Sekcje CDATA | Dosłowny tekst opakowany w <![CDATA[ ... ]]>. Parser nie interpretuje tagów ani encji w środku. Sekwencja ]]> nie może wystąpić wewnątrz bloku CDATA. |
|---|
| Treść mieszana | Elementy mogą zawierać tekst, elementy potomne i białe znaki w dowolnej kolejności. <p>Witaj <b>świecie</b>!</p> to treść mieszana i białe znaki tam są istotne. |
|---|
| Komentarze | <!-- komentarz -->. Nie mogą zawierać -- wewnątrz. Większość procesorów je usuwa, ale ten diff zachowuje je jako tekst. |
|---|
| Kodowanie i BOM | Deklarowane przez <?xml version="1.0" encoding="UTF-8"?>. UTF-8 BOM to ukryty pierwszy znak; częsta przyczyna jednoznakowych fantomowych diffów w linii 1. |
|---|
| XML 1.0 vs 1.1 | Niemal wszyscy używają XML 1.0. Wersja 1.1 dorzuca obsługę dodatkowych znaków sterujących Unicode w treści elementów; w praktyce rzadko spotykane. |
|---|
| Referencje encji | Pięć wbudowanych: & < > ' ". Numeryczne referencje znaków jak é dla liter z akcentem też są poprawne. Samozamykające <br/> i jawne <br></br> są równoważne. |
|---|
XML diff: najczęstsze pytania
Czy zmiana kolejności atrybutów XML albo białe znaki pojawią się jako diff?
Tak, oba się pojawią. Diff tekstowy porównuje znaki linia po linii, więc reformatowanie, zmiana kolejności atrybutów albo białe znaki wewnątrz elementów pojawiają się jako różnice, nawet gdy dokument jest logicznie identyczny. Kliknij najpierw Format w obu panelach, a diff skupi się na prawdziwych zmianach treści. Dla drzew elementów z głęboko zagnieżdżonymi dziećmi porównanie strukturalne przez XSLT albo Canonical XML to kolejny szczebel; to narzędzie obsługuje 95% praktycznych przeglądów XML bez tej złożoności.
Czy kolejność atrybutów na elemencie ma znaczenie?
Nie, dla parsera XML nie. Spec XML 1.0 mówi, że kolejność atrybutów nie jest istotna, więc <img src="a.png" alt="x"/> i <img alt="x" src="a.png"/> reprezentują ten sam element. Diff znakowy i tak zaznaczy reorganizację, bo widzi surowy tekst. Lekarstwo to sformatowanie obu stron tym samym narzędziem, żeby kolejność atrybutów była konsekwentna przed diffem, albo zastosowanie normalizacji Canonical XML, jeśli kontrolujesz pipeline.
Jak namespace'y XML wpływają na diff?
Namespace'y są URI-based, ale wiążesz je z krótkimi prefiksami w dokumencie. Dwa pliki wiążące http://maven.apache.org/POM/4.0.0 z różnymi prefiksami są równoważne według spec Namespaces in XML, ale diff tekstowy zaznaczy każdą zamianę prefiksu jako zmianę. Praktyczne lekarstwo to sformatowanie obu plików i użycie identycznych prefiksów po obu stronach. W zautomatyzowanych pipeline'ach przejście Canonical XML normalizuje to.
Czy mogę diffować pliki XML z sekcjami CDATA?
Tak. Sekcje CDATA to po prostu treść tekstowa z poleceniem dla parsera, żeby jej nie interpretował, więc <![CDATA[<b>raw</b>]]> jest porównywane jako dosłowne znaki w środku. Długie bloki CDATA (script tagi, osadzony HTML, SQL) diffują się czysto. Jeden haczyk to to, że nie możesz mieć ]]> wewnątrz sekcji CDATA; jeśli Twoje dane zawierają tę sekwencję, źródło musi rozdzielić je na dwa bloki CDATA, co diff pokaże tak, jak jest zapisane.
Czy powinienem użyć XSLT zamiast diffu?
XSLT używaj, gdy chcesz przekształcić XML albo znormalizować go przed porównaniem (sortowanie dzieci, wyrzucenie komentarzy, kanonikalizacja namespace'ów). Tego diffu używaj, gdy chcesz zobaczyć, co zmieniło się między dwoma konkretnymi plikami. Te dwa się uzupełniają: wstępne przejście XSLT plus ten diff to mocny flow dla hałaśliwego, generowanego maszynowo XML. Dla większości przypadków code review (pom.xml, AndroidManifest, application context) sam diff wystarczy.
Czy deklaracja kodowania albo BOM wpływają na porównanie?
Trochę. Deklaracja <?xml version="1.0" encoding="UTF-8"?> jest częścią tekstu dokumentu, więc zamiana UTF-8 na UTF-16 pojawia się jako jednolinijkowy diff. Byte order mark (BOM) UTF-8 na samym początku to pojedynczy ukryty znak, który niektóre edytory usuwają, a inne zachowują, częste źródło fantomowych diffów. Jeśli dwa pliki wyglądają identycznie, ale diff pokazuje zmianę w linii 1 znak 0, podejrzewaj BOM i zapisz ponownie ze znanym ustawieniem kodowania.
Prywatność i jak to działa
Twój XML nigdy nie wychodzi z przeglądarki. Parser, formatter i diff działają wszystkie na Twoim komputerze, lokalnie. Bez analityki na Twoim wejściu, bez logów, bez "pomocnego" wyjazdu do chmury. Parsing i walidacja korzystają z natywnego DOMParser przeglądarki, a spec, której się trzymamy, to W3C XML 1.0. Lektura uzupełniająca o samym formacie jest na Wikipedii.