简体   繁体   中英

Using Python LXML to removing XML element values but leaving one placeholder

I have an XML file which I would like to clear the text in the 'value' child elements, but leave one empty value element as a placeholder for adding text at a later date. I am using Python's LXML module.

Here's an example of the XML section:

<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>

And here's what I am hoping to output:

<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>

I have written the following code, but it only adds the "value" tag to the last element:

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)

I would remove all value elements and append an empty one in a single loop:

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)

There is also a handy .clear() method , but it would also clear up the attributes.


The reason your current approach is not working is because you are trying to reuse the same exact blankval element, but instead, you need to recreate new element in the loop before you perform an insert operation:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM