3

我正在尝试检查 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() 函数,它只会“组成”一个标题。

有没有办法用 ET 检查 xml 标头?或者在使用 ET.parse 加载文件时以某种方式抛出错误,如果文件不包含 xml 标头?

4

1 回答 1

1

tl;博士

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

来自维基百科的 XML 声明

如果 XML 文档缺少编码规范,则 XML 解析器假定编码是 UTF-8 或 UTF-16,除非编码已经由更高的协议确定。

...

可以选择省略该声明,因为它声明了默认编码作为其编码。但是,如果文档改为使用 XML 1.1 或其他字符编码,则需要声明。版本 7 之前的 Internet Explorer 进入怪异模式,如果它在作为 text/html 的文档中遇到 XML 声明

因此,即使 XML 文档中省略了 XML 声明,代码片段:

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

将在此 XML 文档中找到“the”默认 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))

这是一个工作小提琴 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"?>
于 2019-03-01T10:24:05.310 回答