【问题标题】:Clean xml ==> Remove line if any empty tags清理 xml ==> 如果有空标签,则删除行
【发布时间】:2015-06-04 19:27:35
【问题描述】:

我想清理我的 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)

完成上述任务的最佳方法是什么?

【问题讨论】:

  • 为什么不删除空节点,而它仍然是 XML,而不是尝试在它是字符串时这样做?
  • “空标签”是什么意思?你的意思是一个独立的标签,即使它有属性?
  • 使用正则表达式路由这可能有效(?s)&lt;[\w:]+(?:\s+(?:".*?"|'.*?'|[^&gt;]*?)+)?/&gt;

标签: python regex xml


【解决方案1】:

使用 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)

【讨论】:

    【解决方案2】:

    此解决方案可考虑用于 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>
    """
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-16
      • 2022-03-16
      • 1970-01-01
      • 1970-01-01
      • 2020-12-16
      • 2011-03-10
      • 2020-11-23
      相关资源
      最近更新 更多