使用minidom处理XML时,有没有办法可以保留属性的原始顺序?
说我有:<color red="255" green="255" blue="233" />
当我用minidom修改它时,属性按字母顺序重新排列为蓝色,绿色和红色。我想保留原来的订单。
我通过循环遍历elements = doc.getElementsByTagName('color')
返回的元素来处理文件,然后我执行这样的分配e.attributes["red"].value = "233"
。
答案 0 :(得分:9)
为了保持属性顺序,我在minidom中做了一点修改:
from collections import OrderedDict
在Element类中:
__init__(...)
self._attrs = OrderedDict()
#self._attrs = {}
writexml(...)
#a_names.sort()
现在这只适用于Python 2.7+ 我不确定它是否真的有效=&gt;使用风险自负......
请注意,您不应该依赖属性顺序:
请注意,start-tag或empty-element标记中的属性规范顺序并不重要。
答案 1 :(得分:8)
使用minidom处理XML时,有没有办法可以保留属性的原始顺序?
使用minidom no时,用于存储属性的数据类型是无序字典。 pxdom可以做到这一点,但速度要慢得多。
答案 2 :(得分:3)
很明显,xml属性没有排序。 我刚刚发现了这种奇怪的行为!
这似乎与xml.dom.minidom.Element.writexml函数中添加的排序有关!!
class Element(Node):
... snip ...
def writexml(self, writer, indent="", addindent="", newl=""):
# indent = current indentation
# addindent = indentation to add to higher levels
# newl = newline string
writer.write(indent+"<" + self.tagName)
attrs = self._get_attributes()
a_names = attrs.keys()
a_names.sort()
--------^^^^^^^^^^^^^^
for a_name in a_names:
writer.write(" %s=\"" % a_name)
_write_data(writer, attrs[a_name].value)
writer.write("\"")
删除该行可恢复保持原始文档顺序的行为。 当您必须使用diff工具检查代码中没有错误时,这是一个好主意。
答案 3 :(得分:3)
在Python 2.7之前,我使用了以下 hotpatching :
class _MinidomHooker(object):
def __enter__(self):
minidom.NamedNodeMap.keys_orig = minidom.NamedNodeMap.keys
minidom.NamedNodeMap.keys = self._NamedNodeMap_keys_hook
return self
def __exit__(self, *args):
minidom.NamedNodeMap.keys = minidom.NamedNodeMap.keys_orig
del minidom.NamedNodeMap.keys_orig
@staticmethod
def _NamedNodeMap_keys_hook(node_map):
class OrderPreservingList(list):
def sort(self):
pass
return OrderPreservingList(node_map.keys_orig())
以这种方式使用:
with _MinidomHooker():
document.writexml(...)
声明:
答案 4 :(得分:2)
你们可以提出你想要的免责声明。 虽然重新排序属性对程序没有意义,但它确实对程序员/用户有意义。
对于Fredrick来说,重要的是要有RGB顺序,因为这就是颜色的顺序。 对我来说,它特别是name属性。
比较
<field name="url" type="string" indexed="true" stored="true" required="true" multiValued="false"/> <!-- ID -->
<field name="forkortelse" type="string" indexed="true" stored="true" required="false" multiValued="false" />
<field name="kortform" type="text_general" indexed="true" stored="true" required="false" multiValued="false" />
<field name="dato" type="date" indexed="true" stored="true" required="false" multiValued="false" />
<field name="nummer" type="int" indexed="true" stored="true" required="false" multiValued="false" />
<field name="kilde" type="string" indexed="true" stored="true" required="false" multiValued="false" />
<field name="tittel" type="text_general" indexed="true" stored="true" multiValued="true"/>
反
<field indexed="true" multiValued="false" name="forkortelse" required="false" stored="true" type="string"/>
<field indexed="true" multiValued="false" name="kortform" required="false" stored="true" type="text_general"/>
<field indexed="true" multiValued="false" name="dato" required="false" stored="true" type="date"/>
<field indexed="true" multiValued="false" name="nummer" required="false" stored="true" type="int"/>
<field indexed="true" multiValued="false" name="kilde" required="false" stored="true" type="string"/>
<field an_optional_attr="OMG!" an_optional_attr2="OMG!!" indexed="true" name="tittel" stored="true" type="text_general"/>
虽然阅读并非不可能,但并不容易。名称是重要的属性。隐藏名称字段的方式并不好。如果名称是左边的15个属性,前面的7个属性是可选的,该怎么办?
重点是重新排序是一个比acsending排序反过来更大的问题。它与程序员的思维方式或功能如何运作相混淆。至少顺序应该是可配置/可选的。
请原谅我可怜的英语。这不是我的主要语言。
答案 5 :(得分:1)
1.定制您自己的&#39; Element.writexml&#39;方法强>
来自&#39; minidom.py&#39;将Element的writexml代码复制到您自己的文件中。将其重命名为writexml_nosort,
删除&#39; a_names.sort()&#39; (python 2.7) 或更改&#39; a_names =已排序(attrs.keys())&#39;到&#39; a_names = attrs.keys()&#39;(python 3.4)
将Element的方法更改为您自己的方法:
minidom.Element.writexml = writexml_nosort;
2.自定义您喜欢的订单:
right_order = [&#39; a&#39;,&#39; b&#39;,&#39; c&#39;,&#39; a1&#39;,&#39; b1&#39; ]
3.调整您的元素_atters
node._attrs = OrderedDict(right_order中k的[(k,node._attrs [k])])
答案 6 :(得分:0)
在Element类中使用writexlm函数编写时,属性按最小顺序排列。 这样完成:
a-name = sorted(attrs.keys())
您可以将其更改为
a-name = list(attrs.keys())
对于空闲状态,我不得不在
/usr/lib/python3.6/xml/dom
。空闲似乎没有遵循sys.path
的顺序。
别忘了先备份。
答案 7 :(得分:0)
在处理XML时,有没有一种方法可以保留属性的原始顺序 渺小?
是的。从Python 3.8开始,序列化XML文档时将保留原始属性顺序。
请参见https://docs.python.org/3/library/xml.dom.minidom.html#xml.dom.minidom.Node.writexml。
答案 8 :(得分:-1)
我最终使用lxml库而不是minidom。