Znění hlášky v jednotlivých parserech
libxml2 (PHP, xmllint, lxml) hlásí Opening and ending tag mismatch, Java The element type "…" must be terminated by the matching end-tag "</…>", Python a Firefox mismatched tag, Chrome Unexpected closing tag:
Hláška libxml2 obsahuje dvě jména: první je otevřený element i s řádkem, kde začal
(polozka line 3), druhé uzavírací značka, na které parser skončil. Java a Firefox
jmenují jen otevřený element, .NET uvádí obojí i s pozicemi.
Příčiny a opravy
Překlep nebo jiná velikost písmen v uzavírací značce
<?xml version="1.0" encoding="UTF-8"?>
<objednavka>
<polozka>Hrnek</Polozka>
</objednavka> <?xml version="1.0" encoding="UTF-8"?>
<objednavka>
<polozka>Hrnek</polozka>
</objednavka>
XML rozlišuje velká a malá písmena, <polozka> a
</Polozka> jsou dva různé názvy. Stejně se projeví překlep
(</polzka>) nebo přejmenování jen otevírací značky.
Chybějící uzavírací značka
<?xml version="1.0" encoding="UTF-8"?>
<objednavka>
<polozka>Hrnek
<cena>199</cena>
</objednavka> <?xml version="1.0" encoding="UTF-8"?>
<objednavka>
<polozka>Hrnek</polozka>
<cena>199</cena>
</objednavka>
Parser si všimne až u </objednavka>, kdy čeká nejdřív
</polozka>. Hlášený řádek je proto až konec nadřazeného elementu. Hledej
otevírací značku, kterou hláška jmenuje (libxml2 přidává i její řádek).
Křížené značky
<?xml version="1.0" encoding="UTF-8"?>
<poznamka>Zboží je <b><i>skladem</b></i></poznamka> <?xml version="1.0" encoding="UTF-8"?>
<poznamka>Zboží je <b><i>skladem</i></b></poznamka> HTML prohlížeč křížené značky tiše opraví, XML parser ne. Značky se musí uzavírat v opačném pořadí, než se otevřely. Častý zdroj je text zkopírovaný z HTML do elementu popisu — takový text patří do sekce CDATA, nebo se musí escapovat.
Useknutý soubor
<?xml version="1.0" encoding="UTF-8"?>
<objednavky>
<objednavka cislo="2026-117"/>
<objednavka cislo="2026-118"/> <?xml version="1.0" encoding="UTF-8"?>
<objednavky>
<objednavka cislo="2026-117"/>
<objednavka cislo="2026-118"/>
</objednavky> Když soubor skončí uprostřed, žádná špatná uzavírací značka v něm není. libxml2 hlásí Premature end of data in tag, Java XML document structures must start and end within the same entity, Python no element found. Příčinou bývá přerušené stahování, plný disk, zápis bez zavření souboru nebo export s limitem velikosti. Oprava není v XML, ale v tom, co soubor vytvořilo — stáhni ho znovu a porovnej velikost.
Jak chybu najít
- Nejdřív se podívej na element, který hláška jmenuje jako otevřený, ne na řádek, kde parser skončil.
- V editoru s podporou XML (VS Code, Notepad++) sbal elementy od kořene dolů. Element, který nejde sbalit tam, kde čekáš, je ten neuzavřený.
- Validátor na XML.cz u neuzavřeného elementu zvýrazní i jeho otevírací značku, takže vidíš oba konce problému najednou.
- U velkých souborů pomůže porovnat soubor s poslední verzí, která fungovala, a podívat se jen na změněná místa.
Prevence v kódu
Neuzavřené a překlepnuté značky skoro vždy vznikají skládáním XML z řetězců. Knihovna, která dokument sestaví ze stromu, značky uzavře sama:
import xml.etree.ElementTree as ET
objednavka = ET.Element("objednavka")
ET.SubElement(objednavka, "polozka").text = "Hrnek"
ET.SubElement(objednavka, "cena").text = "199"
ET.ElementTree(objednavka).write("objednavka.xml", encoding="UTF-8", xml_declaration=True)
Obdobně poslouží DOMDocument v PHP, XDocument v .NET nebo
XMLStreamWriter v Javě. Postupy pro jednotlivé jazyky jsou v kapitolách
XML v PHP, XML v C# a
XML v JavaScriptu.
Související
- Časté chybové hlášky parseru v kapitole Jak funguje XML.
- HTML chybová stránka místo XML — neuzavřené
<hr>nebo<br>v odpovědi serveru. - Přehled všech chybových hlášek.