我使用ElementTree在python中编写了一个相当简单的过滤器,以调整某些xml文件的上下文。它或多或少地起作用。
但是它重新排序了各种标签的属性,我希望它不要这样做。
有谁知道我可以抛出的开关使其保持在指定的顺序?
我正在使用一个粒子物理工具,该工具具有基于xml文件的复杂但奇怪的配置系统。以这种方式设置的许多事物中包括各种静态数据文件的路径。这些路径被硬编码到现有的xml中,没有基于环境变量设置或更改它们的功能,在我们的本地安装中,它们必须位于不同的位置。
这不是灾难,因为我们使用的源代码控制和构建控制工具相结合,使我们可以使用本地副本对某些文件进行阴影处理。但是,即使以为数据字段是静态的,xml也不是静态的,所以我写了一个脚本来修复路径,但是由于属性重排,本地版本和主版本之间的差异很难理解,因此不必要。
这是我第一次带ElementTree旋转(而且只有我的第五个或第六个python项目),所以也许我只是做错了。
为简化起见,代码摘要如下:
tree = elementtree.ElementTree.parse(inputfile)
i = tree.getiterator()
for e in i:
e.text = filter(e.text)
tree.write(outputfile)
在@bobince的答案和这两个帮助下(设置属性顺序,覆盖模块方法)
我设法修复了这只猴子的脏污,建议使用另一个模块更好地处理这种情况,但是在这种情况下是不可能的:
# =======================================================================
# Monkey patch ElementTree
import xml.etree.ElementTree as ET
def _serialize_xml(write, elem, encoding, qnames, namespaces):
tag = elem.tag
text = elem.text
if tag is ET.Comment:
write("<!--%s-->" % ET._encode(text, encoding))
elif tag is ET.ProcessingInstruction:
write("<?%s?>" % ET._encode(text, encoding))
else:
tag = qnames[tag]
if tag is None:
if text:
write(ET._escape_cdata(text, encoding))
for e in elem:
_serialize_xml(write, e, encoding, qnames, None)
else:
write("<" + tag)
items = elem.items()
if items or namespaces:
if namespaces:
for v, k in sorted(namespaces.items(),
key=lambda x: x[1]): # sort on prefix
if k:
k = ":" + k
write(" xmlns%s=\"%s\"" % (
k.encode(encoding),
ET._escape_attrib(v, encoding)
))
#for k, v in sorted(items): # lexical order
for k, v in items: # Monkey patch
if isinstance(k, ET.QName):
k = k.text
if isinstance(v, ET.QName):
v = qnames[v.text]
else:
v = ET._escape_attrib(v, encoding)
write(" %s=\"%s\"" % (qnames[k], v))
if text or len(elem):
write(">")
if text:
write(ET._escape_cdata(text, encoding))
for e in elem:
_serialize_xml(write, e, encoding, qnames, None)
write("</" + tag + ">")
else:
write(" />")
if elem.tail:
write(ET._escape_cdata(elem.tail, encoding))
ET._serialize_xml = _serialize_xml
from collections import OrderedDict
class OrderedXMLTreeBuilder(ET.XMLTreeBuilder):
def _start_list(self, tag, attrib_in):
fixname = self._fixname
tag = fixname(tag)
attrib = OrderedDict()
if attrib_in:
for i in range(0, len(attrib_in), 2):
attrib[fixname(attrib_in[i])] = self._fixtext(attrib_in[i+1])
return self._target.start(tag, attrib)
# =======================================================================
然后在您的代码中:
tree = ET.parse(pathToFile, OrderedXMLTreeBuilder())
问题内容: 我正在编写一个Java程序,该程序读取xml文件,进行一些修改并写回xml。 使用标准的Java xml DOM api,不会保留属性的顺序。也就是说,如果我有一个输入文件,例如: 我可能会得到一个输出文件: 是正确的,因为XML规范说order属性并不重要。 但是,我的程序需要保留属性的顺序,以便一个人可以使用diff工具轻松比较输入和输出文档。 一种解决方案是使用SAX(而不是DO
问题内容: TL; DR; 我正在寻找一个可以查找特定中间操作或终端操作的地方。在哪里可以找到此类文档? 编辑 这不是如何确保java8流中的处理顺序的重复项?,因为该问题未提供完整的操作列表。 该软件包的文件说: 流是否具有遇到顺序取决于源和中间操作 为了确保在整个流操作中维持顺序,您必须研究流源,所有中间操作和终端操作的文档,以了解它们是否维持顺序(或源是否在第一个顺序中具有顺序)地点)。 一
问题内容: 在以最小方式处理XML时,有什么方法可以保留属性的原始顺序吗? 说我有: 当我用最小修改它时,属性按字母顺序重新排列为蓝色,绿色和红色。我想保留原始顺序。 我通过遍历返回的元素来处理文件,然后进行这样的分配。 问题答案: 在以最小方式处理XML时,有什么方法可以保留属性的原始顺序吗? 如果为“ no”,则用于存储属性的数据类型是无序字典。pxdom可以做到,尽管它的速度要慢得多。
问题内容: Java Set是否保留顺序?有一种方法将Set返回给我,并且假定数据是有序的,但是遍历Set时,数据是无序的。有没有更好的方法来解决这个问题?是否需要更改方法以返回Set以外的内容? 问题答案: 该Set接口不提供任何订购保证。 它的子接口代表根据某种标准排序的集合。在Java 6中,有两个实现的标准容器。他们是和。 除了SortedSet接口之外,还有类。它记住元素插入到集合中的顺
几天来我一直在想办法解决这个问题。糟糕的是,hibernate没有提供ready to use annotation来将属性排除在脏检查之外。问题是,我有一节课,如下所示
包含由管道分隔的数字列表的文件可以有重复项。需要编写map reduce程序,在原始输入顺序中列出不重复的数字。我可以删除重复项,但不保留输入顺序。