Delete multiple nodes of the same name

Suppose I have an XML tree as following:

my_data.xml
<?xml version="1.0" encoding="UTF-8"?>
<data>    
  <country name="Singapore" xmlns="aaa:bbb:ccc:singapore:eee">
    <continent>Asia</continent>
    <rank updated="yes">5</rank>
    <year>2011</year>
    <gdppc>59900</gdppc>
    <neighbor name="Malaysia" direction="N"/>
  </country>
  <country name="Panama" xmlns="aaa:bbb:ccc:panama:eee">
    <rank updated="yes">69</rank>
    <year>2011</year>
    <gdppc>13600</gdppc>
    <neighbor name="Costa Rica" direction="W"/>
    <neighbor name="Colombia" direction="E"/>
  </country>
  <ethnicity xmlns="aaa:bbb:ccc:ethnicity:eee">
    <maylay>
      <holidays>ramadan</holidays>
      <holidays>eid al fitri</holidays>
    </malay>
  </ethnicity>
</data>

Parsing the tree with lxml:

import lxml.etree as etree

xtree = etree.parse('my_data.xml')
xroot = xtree.getroot()
malay_node = xroot.xpath('.//*[local-name()="malay"]')[0]
malay_holiday_nodes = xroot.xpath('.//*[local-name()="holidays"]')

I want to delete simultaneously all the holidays nodes under node malay. Note that malay_holiday_nodes is a list. If I do this:

malay_node.remove(malay_holiday_nodes)

I get this error:

TypeError: Argument 'element' has incorrect type (expected lxml.etree._Element, got list)

Any simple way to remove the whole list of child nodes like this without a for loop? Thanks.

Answer

An alternative to using XSLT (which I’m a big fan and user of) is to use lxml’s strip_elements()

from lxml import etree

tree = etree.parse("my_data.xml")

etree.strip_elements(tree, "{*}holidays", with_tail=True)

tree.write("output.xml")

Output (“output.xml”) using your sample XML with the maylay/malay tag mismatch fixed…

<data>
  <country xmlns="aaa:bbb:ccc:singapore:eee" name="Singapore">
    <continent>Asia</continent>
    <rank updated="yes">5</rank>
    <year>2011</year>
    <gdppc>59900</gdppc>
    <neighbor name="Malaysia" direction="N"/>
  </country>
  <country xmlns="aaa:bbb:ccc:panama:eee" name="Panama">
    <rank updated="yes">69</rank>
    <year>2011</year>
    <gdppc>13600</gdppc>
    <neighbor name="Costa Rica" direction="W"/>
    <neighbor name="Colombia" direction="E"/>
  </country>
  <ethnicity xmlns="aaa:bbb:ccc:ethnicity:eee">
    <malay>
      </malay>
  </ethnicity>
</data>