Проверка наличия декларации XML - PullRequest
0 голосов
/ 22 февраля 2019

Я пытаюсь проверить, содержит ли файл xml необходимое объявление xml («заголовок»), скажем:

<?xml version="1.0" encoding="UTF-8"?>
...rest of xml file...

Я использую xml ElementTree для чтения и извлечения информации из файла,но кажется, что файл загружается нормально, даже если у него нет заголовка.

Пока я пробовал вот что:

import xml.etree.ElementTree as ET
tree = ET.parse(someXmlFile)    

try:
    xmlFile = ET.tostring(tree.getroot(), encoding='utf8').decode('utf8')
except:
    sys.stderr.write("Wrong xml2 header\n")
    exit(31)

if re.match(r"^\s*<\?xml version=\'1\.0\' encoding=\'utf8\'\?>\s+", xmlFile) is None:
    sys.stderr.write("Wrong xml1 header\n")
    exit(31)

Но функция ET.tostring () просто«составляет» заголовок, если его нет в файле.

Есть ли способ проверить заголовок xml с ET?Или как-то выдать ошибку при загрузке файла с ET.parse, если файл не содержит заголовок xml?

1 Ответ

0 голосов
/ 01 марта 2019

tl; др

from xml.dom.minidom import parseString
def has_xml_declaration(xml):
    return parseString(xml).version

Из XML-декларация Википедии

Если в документе XML отсутствует спецификация кодировки, то XMLparser предполагает, что кодировка UTF-8 или UTF-16, если только кодировка не была определена более высоким протоколом.

...

Объявление можетможет быть опущен, поскольку он объявляет в качестве своей кодировки кодировку по умолчанию.Однако, если документ вместо этого использует XML 1.1 или другую кодировку символов, объявление необходимо.Internet Explorer до версии 7 переходит в режим причуд, если он встречает объявление XML в документе, который используется как text / html

Таким образом, даже если объявление XML отсутствует в документе XML, фрагмент кода:

if re.match(r"^<\?xml\s*version=\'1\.0\' encoding=\'utf8\'\s*\?>", xmlFile.decode('utf-8')) is None:

найдет "XML-объявление по умолчанию" в этом XML-документе.Обратите внимание, что я использовал xmlFile.decode ('utf-8') вместо xmlFile.Если вы не беспокоитесь об использовании minidom, вы можете использовать следующий фрагмент кода:

from xml.dom.minidom import parse

dom = parse('bookstore-003.xml')
print('<?xml version="{}" encoding="{}"?>'.format(dom.version, dom.encoding))

Вот рабочее fiddle Int bookstore-001.xml объявление XMLотсутствует в bookstore-002.xml объявление XML отсутствует, а в bookstore-003.xml объявление XML отличается от первого примера.Инструкция print печатает соответственно версию и кодировку:

<?xml version="1.0" encoding="UTF-8"?>

<?xml version="None" encoding="None"?>

<?xml version="1.0" encoding="ISO-8859-1"?>
...