我有一个XML编写脚本,它为特定的第三方工具输出XML。
我使用原始XML作为模板,以确保构建的元素都是正确的,但是最终的XML看起来不像原始的。
我按相同的顺序编写属性,但lxml是按自己的顺序编写的。
我不确定,但我怀疑第三部分工具希望属性以特定的顺序出现,我想解决这个问题,这样我就可以看到使它失败的是attrib顺序还是其他什么。
源元素:
<FileFormat ID="1" Name="Development Signature" PUID="dev/1" Version="1.0" MIMEType="text/x-test-signature">
我的源脚本:
sig.fileformat = etree.SubElement(sig.fileformats, "FileFormat", ID = str(db.ID), Name = db.name, PUID="fileSig/{}".format(str(db.ID)), Version = "", MIMEType = "")
生成的XML:
<FileFormat MIMEType="" PUID="fileSig/19" Version="" Name="Printer Info File" ID="19">
有没有办法限制它们的书写顺序?
属性的有序化
从lxml 3.3.3开始(可能也在早期版本中),您可以将属性的OrderedDict传递给
lxml.etree.(Sub)Element
构造函数,使用lxml.etree.tostring(root)
时将保留顺序:注意,ElementTree API(
xml.etree.ElementTree
)不会保留属性顺序,即使您向xml.etree.ElementTree.(Sub)Element
构造函数提供了OrderedDict
!更新:还请注意,使用
lxml.etree.(Sub)Element
构造函数的**extra
参数指定属性并不会保留属性顺序:属性排序和可读性 正如注释者所提到的,属性顺序在XML中没有语义意义,也就是说它不会改变元素的含义:
在SQL中有一个类似的特性,列顺序不变 表定义的含义。XML属性和SQL列是一个集合 (不是有序集),因此可以“正式”地说 其中之一是属性或列是否存在于集合中。
也就是说,它肯定会对人类的可读性产生影响 这些东西出现在像这样的构造被编写并出现在文本(例如源代码)中并且必须被解释的情况下,一个谨慎的排序对我来说很有意义。
典型的解析器行为
任何将属性顺序视为重要的XML解析器都将不符合XML标准。这并不意味着它不可能发生,但根据我的经验,这肯定是不寻常的。不过,取决于你提到的工具的出处,这是一个值得测试的可能性。
据我所知,
lxml
没有指定序列化XML中出现的order属性的机制,如果有,我会感到惊讶。为了测试行为,我强烈倾向于编写一个基于文本的模板来生成足够的XML来测试它:
看起来lxml按设置顺序序列化属性:
注意,当使用ET.SubElement()构造函数传递属性时,Python将构造一个关键字参数字典并将该字典传递给lxml。这会丢失源文件中的任何顺序,因为Python的字典是无序的(或者,它们的顺序是由字符串散列值决定的,这些散列值可能因平台而异,或者实际上因执行而异)。
相关问题 更多 >
编程相关推荐