清洁xml ==>如果有任何空标签,请删除行

时间:2015-06-04 19:27:36

标签: python regex xml

我想清理我的xml,这样它不仅是有效的XML,而且还以一种非常人性化的方式进行格式化。例如:

<Items>
    <Name>Hello</Name>
    <Cost>9.99</Cost>
    <Condition/>
</Items>

我想删除任何带有空标记的行,并留下:

<Items>
    <Name>Hello</Name>
    <Cost>9.99</Cost>
</Items>

我尝试使用正则表达式进行此操作,但在将其保留为可读格式方面没有多少运气:

txt = etree.tostring(self.xml_node, pretty_print=True)
txt = re.sub(r'<[a-zA-Z]+/>\n', '', txt)

实现上述目标的最佳方法是什么?

2 个答案:

答案 0 :(得分:5)

使用 XML解析器

我的想法是find all empty nodes //*[not(node())] XPath表达式和remove them from the tree。例如,使用lxml

from lxml import etree


data = """
<Items>
    <Name>Hello</Name>
    <Cost>9.99</Cost>
    <Condition/>
</Items>
"""

root = etree.fromstring(data)
for element in root.xpath(".//*[not(node())]"):
    element.getparent().remove(element)

print etree.tostring(root, pretty_print=True)

答案 1 :(得分:0)

可以将此解决方案考虑为XML数据的第n级深度。

from lxml import etree

def recursively_empty(xml_element):
   if xml_element.text:
       return False
   return all((recursively_empty(xe) for xe in xml_element.iterchildren()))

data = """
<Items>
    <Name>Hello</Name>
    <Cost>9.99</Cost>
    <Condition/>
</Items>
"""

xml_root = etree.iterwalk(data)

for action, xml_element in xml_root:
    parent = xml_element.getparent()
    if recursively_empty(xml_element):
        parent.remove(xml_element)

请注意:使用递归方法的原因是为了解决多层次的XML数据深度。

解决方案应该适用于各种深度

data1 = """
<Items>
    <Name>Hello</Name>
    <Cost>9.99</Cost>
    <Condition/>
</Items>
"""

data2 = """
<Items>
    <Name>Hello</Name>
    <Cost>9.99</Cost>
    <Condition>
        <cond1>Somedata</cond1>
    </Condition>
</Items>
"""

data3 = """
<Items>
    <Name>Hello</Name>
    <Cost>9.99</Cost>
    <Condition>
        </cond1>
    </Condition>
</Items>
"""