【问题标题】:Using Python LXML to removing XML element values but leaving one placeholder使用 Python LXML 删除 XML 元素值但留下一个占位符
【发布时间】:2017-01-12 14:39:03
【问题描述】:

我有一个 XML 文件,我想清除“值”子元素中的文本,但留下一个空值元素作为占位符,以便以后添加文本。我正在使用 Python 的 LXML 模块。

以下是 XML 部分的示例:

<spec class="Spec" name="New Test">
    <mainreport>
        <item name="New Item">First Item</item>
    </mainreport>

    <case class="CaseItem" name="Some Name">
        <extraelement>
            <item name="ID">Some Id</item>

        </extraelement>

        <pool class="String" name="Originator">
            <value>A</value>
            <value>B</value>
            <value>C</value>
        </pool>

        <pool class="String" name="Target">
            <value>D</value>
            <value>E</value>
            <value>F</value>
        </pool>

这是我希望输出的内容:

<spec class="Spec" name="New Test">
    <mainreport>
        <item name="New Item">First Item</item>
    </mainreport>

    <case class="CaseItem" name="Some Name">
        <extraelement>
            <item name="ID">Some Id</item>

        </extraelement>

        <pool class="String" name="Originator">
            <value></value>
        </pool>

        <pool class="String" name="Target">
            <value></value>
        </pool>

我写了以下代码,但它只在最后一个元素添加了“value”标签:

import lxml.etree as et
import os

xml_match = os.path.join("input.xml")
doc = et.parse(xml_match)

for elem in doc.xpath('//case/pool/value'):
    elem.getparent().remove(elem)

blankval = et.Element("value")
blankval.text = ""

for elem in doc.xpath('//case/pool'):
    elem.insert(1, blankval)

outFile = "output.xml"

doc.write(outFile)

【问题讨论】:

    标签: python xml lxml


    【解决方案1】:

    我将删除所有 value 元素并在单个循环中附加一个空元素:

    for elem in doc.xpath('//case/pool'):
        for value in elem.findall("value"):
            elem.remove(value)
    
        blankval = et.Element("value")
        blankval.text = ""
        elem.append(blankval)
    

    还有一个好用的.clear() method,不过也可以清除属性。


    您当前的方法不起作用的原因是您试图重复使用完全相同的 blankval 元素,但是,您需要在执行插入操作之前在循环中重新创建新元素:

    for elem in doc.xpath('//case/pool'):
        blankval = et.Element("value")
        blankval.text = ""
        elem.insert(1, blankval)
    

    【讨论】:

    • 感谢您的帮助@alecxe,现在这很有意义。就像你说的那样,具有讽刺意味的是,我试图通过将过程分解为两个循环来简化任务,这实际上阻碍了我最初的尝试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-18
    • 2021-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多