检查XML声明是否存在

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标头的情况下抛出错误?


1
在 XML 文件中包含 XML 声明是一个好的习惯,但不是强制性要求。这里指出了“应该”:https://www.w3.org/TR/xml/#sec-prolog-dtd - mzjn
嗨,Dennis:你看到我的答案了吗?对你来说这是一个可行的解决方案吗?如果不是,你还有兴趣得到建议/答案吗?感谢你的回复。 - Meziane
1个回答

1
“tl;dr” 的意思是 “太长,不看”。
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或其他字符编码,则需要声明。如果Internet Explorer 7之前的版本在作为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))

这里有一个可用的fiddle。在 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"?>

这里是两个字段被设置的位置。 - x-yuri

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接