来自minidom getElementsByTagName的元素顺序

时间:2016-10-10 11:57:53

标签: python xml python-3.x dom minidom

Mindom getElementsByTagName返回元素的顺序是否与同一层次/级别中元素的文档相同?

    images = svg_doc.getElementsByTagName('image') 
    image_siblings = []
    for img in images:
        if img.parentNode.getAttribute('layertype') == 'transfer':
            if img.nextSibling is not None:
                if img.nextSibling.nodeName == 'image':
                    image_siblings.append(img.nextSibling)
                elif img.nextSibling.nextSibling is not None and img.nextSibling.nextSibling.nodeName == 'image':
                    image_siblings.append(img.nextSibling.nextSibling)

我需要知道image_siblings是否会以相同的顺序包含图像,它们会放在同一层次结构的文档中。

我发现JavaScript的类似question,但我不确定Python(版本3.5.2)Minidom getElementsByTagName是否也是如此。

1 个答案:

答案 0 :(得分:6)

根据代码(在Python 2.7中),getElementsByName方法在_get_elements_by_tagName_helper函数上进行中继,代码为:

def _get_elements_by_tagName_helper(parent, name, rc):
    for node in parent.childNodes:
        if node.nodeType == Node.ELEMENT_NODE and \
            (name == "*" or node.tagName == name):
            rc.append(node)
        _get_elements_by_tagName_helper(node, name, rc)
    return rc

这意味着getElementByName中的订单与childNodes中的订单相同。

但只有当tagName仅出现在同一级别时才会出现这种情况。注意_get_elements_by_tagName_helper在同一个函数内的递归调用,这意味着在树中更深处放置的具有相同tagName的元素将与您在更高级别中的元素交错。

如果 document 是指XML文本文件或字符串,那么问题就会转移到解析器在DOM中创建元素时是否遵守顺序。 如果您使用parse中的xml.dom.minidom函数,它会在pyexpat库中继,然后使用expat C库。

所以,简短的回答是:

  

如果您的tagName仅出现在XML DOM中的相同层次结构中,则会遵循该顺序。如果树中更深的其他节点中具有相同的tagName,则这些元素将与更高级别的元素交错。受尊重的顺序是minidom文档对象中元素的顺序,顺序取决于解析器。

看一下这个例子:

>>> import StringIO
>>> from xml.dom.minidom import parseString
>>> s = '''<head>
...   <tagName myatt="1"/>
...   <tagName myatt="2"/>
...   <tagName myatt="3"/>
...   <otherTag>
...     <otherDeeperTag>
...       <tagName myatt="3.1"/>
...       <tagName myatt="3.2"/>
...       <tagName myatt="3.3"/>
...     </otherDeeperTag>
...   </otherTag> 
...   <tagName myatt="4"/>
...   <tagName myatt="5"/>
... </head>'''
>>> doc = parseString(s)
>>> for e in doc.getElementsByTagName('tagName'):
...     print e.getAttribute('myatt')
... 
1
2
3
3.1
3.2
3.3
4
5

似乎解析器尊重xml字符串的排序结构(大多数解析器都尊重该顺序,因为它更容易尊重它)但我找不到任何证实它的文档。我的意思是,可能是(奇怪的)情况,解析器,根据文档的大小,从使用列表移动到哈希表来存储元素,这可能会破坏顺序。考虑到XML标准没有指定元素的顺序,因此不遵守顺序的解析器也会受到抱怨。