当前位置: 首页 > 面试题库 >

可以告诉ElementTree保留属性的顺序吗?

越涛
2023-03-14
问题内容

我使用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程序,在原始输入顺序中列出不重复的数字。我可以删除重复项,但不保留输入顺序。