Znění hlášky v jednotlivých parserech
XML 1.0 povoluje tabulátor (U+0009), konec řádku (U+000A), návrat vozíku (U+000D) a znaky od
U+0020 výš kromě U+D800–U+DFFF, U+FFFE a U+FFFF (produkce Char). Ostatní řídicí
znaky U+0000–U+001F nejsou povolené v textu, atributech ani jako číselný odkaz. XML 1.1 povoluje
U+0001–U+001F jako číselný odkaz, U+0000 ani tam ne, a v praxi se skoro nepoužívá (viz
XML 1.0 vs 1.1).
Příčiny a opravy
Číselný odkaz na zakázaný znak
<text>bez NUL</text>
Číselný odkaz nepovoluje nic, co nepovoluje samotný text. U+0000 je zakázaný vždy. U běžného
ampersandu nebo menší než jde naopak o syntaxi, kterou vyřeší & nebo
< (viz znak & v XML).
Řídicí znak přímo v textu
<text>ab</text> Řídicí znaky se do XML obvykle dostanou z databáze, z textu zkopírovaného z jiné aplikace nebo z binárních dat. V editoru nejsou vidět. Najdi je podle kódového bodu:
import re
# Řídicí znaky, které XML 1.0 nepovoluje (tabulátor, LF a CR povolené jsou).
zakazane = re.compile(r"[\x00-\x08\x0B\x0C\x0E-\x1F]")
with open("data.xml", encoding="utf-8") as soubor:
for radek, text in enumerate(soubor, 1):
for m in zakazane.finditer(text):
print(radek, m.start() + 1, hex(ord(m.group()))) # 1 8 0x1 Jak chybu opravit
Odstraň znak jen podle pravidel aplikace, nebo binární data přenes jako Base64. Automatické mazání všech netisknutelných znaků může zničit tabulátory a nové řádky. Nejlépe znak odfiltruj už tam, kde XML vzniká, a zjisti, proč se do dat dostal.
Odliš zakázaný znak od chyby kódování
Číselný odkaz � označuje skutečně zakázaný znak U+0000. Jde o jiný problém než nesprávné UTF-8 bajty, které ještě nelze převést na platné znaky. Samotná změna XML deklarace zakázaný znak neopraví.
Pokud jsou zdrojem data, která mohou obsahovat libovolné bajty, přenes je jako Base64 v poli určeném pro binární obsah. Nezahazuj znaky bez rozhodnutí aplikace: tabulátory a konce řádků jsou v XML 1.0 povolené a mohou být součástí významu. Zápis znaků popisují základy XML, diagnostiku bajtů chyby kódování.