在Python ElementTree中,如何判断元素是否为注释?

时间:2017-11-11 02:59:28

标签: python elementtree

我有一个XML文档,如下所示:

<!-- Servlet Context Listener -->
<listener>
<listener-class>
com.company.servlet.StartupShutdownListener
</listener-class>
</listener>
<!-- Servlet Class Definitions -->
<servlet>
<servlet-name>
AdminServlet
</servlet-name>
<servlet-class>
AdminServlet
</servlet-class>
<load-on-startup>
1
</load-on-startup>
</servlet>

为了使它更具人性化,我找到了indent()函数http://effbot.org/zone/element-lib.htm#prettyprint,它使输出更好。

但是,我想进一步格式化Comment元素以使它们更容易看到。例如,只需在每个注释之前和之后添加一个额外的空行,就可以更容易地看到人类的块:

<!-- Servlet Context Listener -->

<listener>
  <listener-class>
    com.company.servlet.StartupShutdownListener
  </listener-class>
</listener>

<!-- Servlet Class Definitions -->

<servlet>
  <servlet-name>AdminServlet</servlet-name>
  <servlet-class>AdminServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

如何在indent()函数中检测Comment元素?

1 个答案:

答案 0 :(得分:2)

在网上搜索同样问题的其他人之后,我转向了源代码(https://svn.python.org/projects/python/trunk/Lib/xml/etree/ElementTree.py)。答案很简单:

import ElementTree as ET

...

def indent(elem, level=0):    # where elem is of type ET.Element
    ....
    if elem.tag is ET.Comment:
        ...

关键是要意识到&#34;标签&#34;常规XML元素上的属性带有XML标记名称(例如,&#34; listener&#34;或&#34; servlet&#34;),对于表示XML注释的Element,它是Comment()函数本身。

这是完整更新的indent()函数,用于执行注释格式化,如上所示:

def indent(elem, level=0, prev_elem=None, prev_level=0):        
    i = "\n" + level*"  "        
    if len(elem):        
        if not elem.text or not elem.text.strip():        
            elem.text = i + "  "        
        if not elem.tail or not elem.tail.strip():        
            elem.tail = i        
        prev_elem_local = elem        
        prev_level_local = level        
        for elem in elem:        
            indent(elem, level+1, prev_elem_local, prev_level_local)        
            prev_elem_local = elem        
            prev_level_local = level + 1        
        if not elem.tail or not elem.tail.strip():        
            elem.tail = i        
    else:        
        if level and (not elem.tail or not elem.tail.strip()):        
            elem.tail = i        
        if elem.tag is ET.Comment:        
            if prev_level == level:        
                prev_elem.tail = "\n" + prev_elem.tail        
            elif prev_level < level:        
                prev_elem.text = "\n" + prev_elem.text        
            elem.tail = "\n" + elem.tail