If I have a Python3 xml.etree.Element
(doc), is it possible to get a list (or iterable, or whatever) of child elements to that Element
, but only one level deep? If so, how can I do this?
(Note: it appears the xml.etree.Element
library is essentially the same for the version of Python I'm using (3.6.8) and the latest version (3.11).)
For example, say I have this xml:
<?xml version="1.0" encoding="UTF-8"?>
<Document>
<name>myName</name>
<SomeLevel1Element>
<SomeLevel2Element>foo</SomeLevel2Element>
</SomeLevel1Element>
<SomeLevel1Element>
<SomeLevel2Element>bar</SomeLevel2Element>
</SomeLevel1Element>
<AnotherLevel1Element>
</AnotherLevel1Element>
</Document>
I want to do something like:
import xml.etree.ElementTree as ET
tree = ET.parse(PATH_TO_XML_FILE)
root = tree.getroot()
direct_children_of_root = <something>
for child in direct_children_of_root:
print(child)
"""
<Element 'name' at 0x123abc>
<Element 'SomeLevel1Element' at 0x123bbc>
<Element 'SomeLevel1Element' at 0x123cbc>
<Element 'AnotherLevel1Element' at 0x123dbc>
"""
I cannot use findall()
, find()
, findtext()
, since I may not know the amount or kinds of child elements of root
.
I cannot use iter()
, since that method appears to give all children of all children elements.
For example, using the same xml as above:
import xml.etree.ElementTree as ET
tree = ET.parse(PATH_TO_XML_FILE)
root = tree.getroot()
elems = root.iter()
for e in elems:
print(e)
"""
<Element 'Document' at 0x123abc>
<Element 'name' at 0x123bbc>
<Element 'SomeLevel1Element' at 0x123cbc>
<Element 'SomeLevel2Element' at 0x123dbc>
<Element 'SomeLevel1Element' at 0x123ebc>
<Element 'SomeLevel2Element' at 0x123fbc>
<Element 'AnotherLevel1Element' at 0x124abc>
"""
CodePudding user response:
xml.etree.ElementTree
has limited support for Xpath.
Using lxml
instead
>>> from lxml import etree
>>> doc = etree.parse('tmp.xml')
>>> parentName = doc.getroot().tag
>>> level1 = doc.xpath(f'//*[parent::{parentName}]')
>>> for e in level1:
... print(e.tag)
...
name
SomeLevel1Element
SomeLevel1Element
AnotherLevel1Element
If xml.etree.ElementTree
is required
>>> level1 = root.findall('.')[0].findall('./*')
>>> for e in level1:
... print(e.tag)
...
name
SomeLevel1Element
SomeLevel1Element
AnotherLevel1Element
CodePudding user response:
list(root)
returns a list with the children of root
.
direct_children_of_root = list(root)
for child in direct_children_of_root:
print(child)
Even simpler is to just iterate over root
directly.
for child in root:
print(child)