Thexml.etree.ElementTree module implements a simple and efficient APIfor parsing and creating XML data.
Changed in version 3.3:This module will use a fast implementation whenever available.Thexml.etree.cElementTree module is deprecated.
Warning
Thexml.etree.ElementTree module is not secure againstmaliciously constructed data. If you need to parse untrusted orunauthenticated data seeXML vulnerabilities.
This is a short tutorial for usingxml.etree.ElementTree (ET inshort). The goal is to demonstrate some of the building blocks and basicconcepts of the module.
XML is an inherently hierarchical data format, and the most natural way torepresent it is with a tree.ET has two classes for this purpose -ElementTree represents the whole XML document as a tree, andElement represents a single node in this tree. Interactions withthe whole document (reading and writing to/from files) are usually doneon theElementTree level. Interactions with a single XML elementand its sub-elements are done on theElement level.
We’ll be using the following XML document as the sample data for this section:
<?xml version="1.0"?><data><countryname="Liechtenstein"><rank>1</rank><year>2008</year><gdppc>141100</gdppc><neighborname="Austria"direction="E"/><neighborname="Switzerland"direction="W"/></country><countryname="Singapore"><rank>4</rank><year>2011</year><gdppc>59900</gdppc><neighborname="Malaysia"direction="N"/></country><countryname="Panama"><rank>68</rank><year>2011</year><gdppc>13600</gdppc><neighborname="Costa Rica"direction="W"/><neighborname="Colombia"direction="E"/></country></data>
We can import this data by reading from a file:
importxml.etree.ElementTreeasETtree=ET.parse('country_data.xml')root=tree.getroot()
Or directly from a string:
root=ET.fromstring(country_data_as_string)
fromstring() parses XML from a string directly into anElement,which is the root element of the parsed tree. Other parsing functions maycreate anElementTree. Check the documentation to be sure.
As anElement,root has a tag and a dictionary of attributes:
>>>root.tag'data'>>>root.attrib{}
It also has children nodes over which we can iterate:
>>>forchildinroot:...print(child.tag,child.attrib)...country {'name': 'Liechtenstein'}country {'name': 'Singapore'}country {'name': 'Panama'}
Children are nested, and we can access specific child nodes by index:
>>>root[0][1].text'2008'
Element has some useful methods that help iterate recursively over allthe sub-tree below it (its children, their children, and so on). For example,Element.iter():
>>>forneighborinroot.iter('neighbor'):...print(neighbor.attrib)...{'name': 'Austria', 'direction': 'E'}{'name': 'Switzerland', 'direction': 'W'}{'name': 'Malaysia', 'direction': 'N'}{'name': 'Costa Rica', 'direction': 'W'}{'name': 'Colombia', 'direction': 'E'}
Element.findall() finds only elements with a tag which are directchildren of the current element.Element.find() finds thefirst childwith a particular tag, andElement.text accesses the element’s textcontent.Element.get() accesses the element’s attributes:
>>>forcountryinroot.findall('country'):...rank=country.find('rank').text...name=country.get('name')...print(name,rank)...Liechtenstein 1Singapore 4Panama 68
More sophisticated specification of which elements to look for is possible byusingXPath.
ElementTree provides a simple way to build XML documents and write them to files.TheElementTree.write() method serves this purpose.
Once created, anElement object may be manipulated by directly changingits fields (such asElement.text), adding and modifying attributes(Element.set() method), as well as adding new children (for examplewithElement.append()).
Let’s say we want to add one to each country’s rank, and add anupdatedattribute to the rank element:
>>>forrankinroot.iter('rank'):...new_rank=int(rank.text)+1...rank.text=str(new_rank)...rank.set('updated','yes')...>>>tree.write('output.xml')
Our XML now looks like this:
<?xml version="1.0"?><data><countryname="Liechtenstein"><rankupdated="yes">2</rank><year>2008</year><gdppc>141100</gdppc><neighborname="Austria"direction="E"/><neighborname="Switzerland"direction="W"/></country><countryname="Singapore"><rankupdated="yes">5</rank><year>2011</year><gdppc>59900</gdppc><neighborname="Malaysia"direction="N"/></country><countryname="Panama"><rankupdated="yes">69</rank><year>2011</year><gdppc>13600</gdppc><neighborname="Costa Rica"direction="W"/><neighborname="Colombia"direction="E"/></country></data>
We can remove elements usingElement.remove(). Let’s say we want toremove all countries with a rank higher than 50:
>>>forcountryinroot.findall('country'):...rank=int(country.find('rank').text)...ifrank>50:...root.remove(country)...>>>tree.write('output.xml')
Our XML now looks like this:
<?xml version="1.0"?><data><countryname="Liechtenstein"><rankupdated="yes">2</rank><year>2008</year><gdppc>141100</gdppc><neighborname="Austria"direction="E"/><neighborname="Switzerland"direction="W"/></country><countryname="Singapore"><rankupdated="yes">5</rank><year>2011</year><gdppc>59900</gdppc><neighborname="Malaysia"direction="N"/></country></data>
TheSubElement() function also provides a convenient way to create newsub-elements for a given element:
>>>a=ET.Element('a')>>>b=ET.SubElement(a,'b')>>>c=ET.SubElement(a,'c')>>>d=ET.SubElement(c,'d')>>>ET.dump(a)<a><b /><c><d /></c></a>
Seehttp://effbot.org/zone/element-index.htm for tutorials and links to otherdocs.
This module provides limited support forXPath expressions for locating elements in atree. The goal is to support a small subset of the abbreviated syntax; a fullXPath engine is outside the scope of the module.
Here’s an example that demonstrates some of the XPath capabilities of themodule. We’ll be using thecountrydata XML document from theParsing XML section:
importxml.etree.ElementTreeasETroot=ET.fromstring(countrydata)# Top-level elementsroot.findall(".")# All 'neighbor' grand-children of 'country' children of the top-level# elementsroot.findall("./country/neighbor")# Nodes with name='Singapore' that have a 'year' childroot.findall(".//year/..[@name='Singapore']")# 'year' nodes that are children of nodes with name='Singapore'root.findall(".//*[@name='Singapore']/year")# All 'neighbor' nodes that are the second child of their parentroot.findall(".//neighbor[2]")
| Syntax | Meaning |
|---|---|
| tag | Selects all child elements with the given tag.For example,spam selects all child elementsnamedspam,spam/egg selects allgrandchildren namedegg in all children namedspam. |
| * | Selects all child elements. For example,*/eggselects all grandchildren namedegg. |
| . | Selects the current node. This is mostly usefulat the beginning of the path, to indicate that it’sa relative path. |
| // | Selects all subelements, on all levels beneath thecurrent element. For example,.//egg selectsallegg elements in the entire tree. |
| .. | Selects the parent element. ReturnsNone if thepath attempts to reach the ancestors of the startelement (the elementfind was called on). |
| [@attrib] | Selects all elements that have the given attribute. |
| [@attrib='value'] | Selects all elements for which the given attributehas the given value. The value cannot containquotes. |
| [tag] | Selects all elements that have a child namedtag. Only immediate children are supported. |
| [position] | Selects all elements that are located at the givenposition. The position can be either an integer(1 is the first position), the expressionlast()(for the last position), or a position relative tothe last position (e.g.last()-1). |
Predicates (expressions within square brackets) must be preceded by a tagname, an asterisk, or another predicate.position predicates must bepreceded by a tag name.
Comment element factory. This factory function creates a special elementthat will be serialized as an XML comment by the standard serializer. Thecomment string can be either a bytestring or a Unicode string.text is astring containing the comment string. Returns an element instancerepresenting a comment.
Writes an element tree or element structure to sys.stdout. This functionshould be used for debugging only.
The exact output format is implementation dependent. In this version, it’swritten as an ordinary XML file.
elem is an element tree or an individual element.
Parses an XML section from a string constant. Same asXML().textis a string containing XML data. Returns anElement instance.
Parses an XML document from a sequence of string fragments.sequence is alist or other sequence containing XML data fragments.parser is anoptional parser instance. If not given, the standardXMLParserparser is used. Returns anElement instance.
New in version 3.2.
Checks if an object appears to be a valid element object.element is anelement instance. Returns a true value if this is an element object.
Parses an XML section into an element tree incrementally, and reports what’sgoing on to the user.source is a filename orfile objectcontaining XML data.events is a tuple of events to report back. Thesupported events are the strings"start","end","start-ns"and"end-ns" (the “ns” events are used to get detailed namespaceinformation). Ifevents is omitted, only"end" events are reported.parser is an optional parser instance. If not given, the standardXMLParser parser is used.parser can only use the defaultTreeBuilder as a target. Returns aniterator providing(event,elem) pairs.
Note
iterparse() only guarantees that it has seen the “>”character of a starting tag when it emits a “start” event, so theattributes are defined, but the contents of the text and tail attributesare undefined at that point. The same applies to the element children;they may or may not be present.
If you need a fully populated element, look for “end” events instead.
Parses an XML section into an element tree.source is a filename or fileobject containing XML data.parser is an optional parser instance. Ifnot given, the standardXMLParser parser is used. Returns anElementTree instance.
PI element factory. This factory function creates a special element thatwill be serialized as an XML processing instruction.target is a stringcontaining the PI target.text is a string containing the PI contents, ifgiven. Returns an element instance, representing a processing instruction.
Registers a namespace prefix. The registry is global, and any existingmapping for either the given prefix or the namespace URI will be removed.prefix is a namespace prefix.uri is a namespace uri. Tags andattributes in this namespace will be serialized with the given prefix, if atall possible.
New in version 3.2.
Subelement factory. This function creates an element instance, and appendsit to an existing element.
The element name, attribute names, and attribute values can be eitherbytestrings or Unicode strings.parent is the parent element.tag isthe subelement name.attrib is an optional dictionary, containing elementattributes.extra contains additional attributes, given as keywordarguments. Returns an element instance.
Generates a string representation of an XML element, including allsubelements.element is anElement instance.encoding[1] isthe output encoding (default is US-ASCII). Useencoding="unicode" togenerate a Unicode string (otherwise, a bytestring is generated).methodis either"xml","html" or"text" (default is"xml").Returns an (optionally) encoded string containing the XML data.
Generates a string representation of an XML element, including allsubelements.element is anElement instance.encoding[1] isthe output encoding (default is US-ASCII). Useencoding="unicode" togenerate a Unicode string (otherwise, a bytestring is generated).methodis either"xml","html" or"text" (default is"xml").Returns a list of (optionally) encoded strings containing the XML data.It does not guarantee any specific sequence, except thatb"".join(tostringlist(element))==tostring(element).
New in version 3.2.
Parses an XML section from a string constant. This function can be used toembed “XML literals” in Python code.text is a string containing XMLdata.parser is an optional parser instance. If not given, the standardXMLParser parser is used. Returns anElement instance.
Parses an XML section from a string constant, and also returns a dictionarywhich maps from element id:s to elements.text is a string containing XMLdata.parser is an optional parser instance. If not given, the standardXMLParser parser is used. Returns a tuple containing anElement instance and a dictionary.
Element class. This class defines the Element interface, and provides areference implementation of this interface.
The element name, attribute names, and attribute values can be eitherbytestrings or Unicode strings.tag is the element name.attrib isan optional dictionary, containing element attributes.extra containsadditional attributes, given as keyword arguments.
A string identifying what kind of data this element represents (theelement type, in other words).
Thetext attribute can be used to hold additional data associated withthe element. As the name implies this attribute is usually a string butmay be any application-specific object. If the element is created froman XML file the attribute will contain any text found between the elementtags.
Thetail attribute can be used to hold additional data associated withthe element. This attribute is usually a string but may be anyapplication-specific object. If the element is created from an XML filethe attribute will contain any text found after the element’s end tag andbefore the next tag.
A dictionary containing the element’s attributes. Note that while theattrib value is always a real mutable Python dictionary, an ElementTreeimplementation may choose to use another internal representation, andcreate the dictionary only if someone asks for it. To take advantage ofsuch implementations, use the dictionary methods below whenever possible.
The following dictionary-like methods work on the element attributes.
Resets an element. This function removes all subelements, clears allattributes, and sets the text and tail attributes toNone.
Gets the element attribute namedkey.
Returns the attribute value, ordefault if the attribute was not found.
Returns the element attributes as a sequence of (name, value) pairs. Theattributes are returned in an arbitrary order.
Returns the elements attribute names as a list. The names are returnedin an arbitrary order.
Set the attributekey on the element tovalue.
The following methods work on the element’s children (subelements).
Adds the elementsubelement to the end of this element’s internal listof subelements. RaisesTypeError ifsubelement is not anElement.
Appendssubelements from a sequence object with zero or more elements.RaisesTypeError if a subelement is not anElement.
New in version 3.2.
Finds the first subelement matchingmatch.match may be a tag nameor apath. Returns an element instanceorNone.namespaces is an optional mapping from namespace prefixto full name.
Finds all matching subelements, by tag name orpath. Returns a list containing all matchingelements in document order.namespaces is an optional mapping fromnamespace prefix to full name.
Finds text for the first subelement matchingmatch.match may bea tag name or apath. Returns the text contentof the first matching element, ordefault if no element was found.Note that if the matching element has no text content an empty stringis returned.namespaces is an optional mapping from namespace prefixto full name.
Deprecated since version 3.2:Uselist(elem) or iteration.
Deprecated since version 3.2:Use methodElement.iter() instead.
Insertssubelement at the given position in this element. RaisesTypeError ifsubelement is not anElement.
Creates a treeiterator with the current element as the root.The iterator iterates over this element and all elements below it, indocument (depth first) order. Iftag is notNone or'*', onlyelements whose tag equalstag are returned from the iterator. If thetree structure is modified during iteration, the result is undefined.
New in version 3.2.
Finds all matching subelements, by tag name orpath. Returns an iterable yielding allmatching elements in document order.namespaces is an optional mappingfrom namespace prefix to full name.
New in version 3.2.
Creates a text iterator. The iterator loops over this element and allsubelements, in document order, and returns all inner text.
New in version 3.2.
Creates a new element object of the same type as this element. Do notcall this method, use theSubElement() factory function instead.
Removessubelement from the element. Unlike the find* methods thismethod compares elements based on the instance identity, not on tag valueor contents.
Element objects also support the following sequence type methodsfor working with subelements:__delitem__(),__getitem__(),__setitem__(),__len__().
Caution: Elements with no subelements will test asFalse. This behaviorwill change in future versions. Use specificlen(elem) orelemisNone test instead.
element=root.find('foo')ifnotelement:# careful!print("element not found, or element has no subelements")ifelementisNone:print("element not found")
ElementTree wrapper class. This class represents an entire elementhierarchy, and adds some extra support for serialization to and fromstandard XML.
element is the root element. The tree is initialized with the contentsof the XMLfile if given.
Replaces the root element for this tree. This discards the currentcontents of the tree, and replaces it with the given element. Use withcare.element is an element instance.
Same asElement.find(), starting at the root of the tree.
Same asElement.findall(), starting at the root of the tree.
Same asElement.findtext(), starting at the root of the tree.
Deprecated since version 3.2:Use methodElementTree.iter() instead.
Returns the root element for this tree.
Creates and returns a tree iterator for the root element. The iteratorloops over all elements in this tree, in section order.tag is the tagto look for (default is to return all elements)
Same asElement.iterfind(), starting at the root of the tree.
New in version 3.2.
Loads an external XML section into this element tree.source is a filename orfile object.parser is an optional parser instance.If not given, the standardXMLParser parser is used. Returns thesection root element.
Writes the element tree to a file, as XML.file is a file name, or afile object opened for writing.encoding[1] is the outputencoding (default is US-ASCII).xml_declaration controls if an XML declaration should be added to thefile. UseFalse for never,True for always,Nonefor only if not US-ASCII or UTF-8 or Unicode (default isNone).default_namespace sets the default XML namespace (for “xmlns”).method is either"xml","html" or"text" (default is"xml").
The output is either a string (str) or binary (bytes).This is controlled by theencoding argument. Ifencoding is"unicode", the output is a string; otherwise, it’s binary. Note thatthis may conflict with the type offile if it’s an openfile object; make sure you do not try to write a string to abinary stream and vice versa.
This is the XML file that is going to be manipulated:
<html><head><title>Examplepage</title></head><body><p>Movedto<ahref="http://example.org/">example.org</a>or<ahref="http://example.com/">example.com</a>.</p></body></html>
Example of changing the attribute “target” of every link in first paragraph:
>>>fromxml.etree.ElementTreeimportElementTree>>>tree=ElementTree()>>>tree.parse("index.xhtml")<Element 'html' at 0xb77e6fac>>>>p=tree.find("body/p")# Finds first occurrence of tag p in body>>>p<Element 'p' at 0xb77ec26c>>>>links=list(p.iter("a"))# Returns list of all links>>>links[<Element 'a' at 0xb77ec2ac>, <Element 'a' at 0xb77ec1cc>]>>>foriinlinks:# Iterates through all found links...i.attrib["target"]="blank">>>tree.write("output.xhtml")
QName wrapper. This can be used to wrap a QName attribute value, in orderto get proper namespace handling on output.text_or_uri is a stringcontaining the QName value, in the form {uri}local, or, if the tag argumentis given, the URI part of a QName. Iftag is given, the first argument isinterpreted as an URI, and this argument is interpreted as a local name.QName instances are opaque.
Generic element structure builder. This builder converts a sequence ofstart, data, and end method calls to a well-formed element structure. Youcan use this class to build an element structure using a custom XML parser,or a parser for some other XML-like format.element_factory, when given,must be a callable accepting two positional arguments: a tag anda dict of attributes. It is expected to return a new element instance.
Flushes the builder buffers, and returns the toplevel documentelement. Returns anElement instance.
Adds text to the current element.data is a string. This should beeither a bytestring, or a Unicode string.
Closes the current element.tag is the element name. Returns theclosed element.
Opens a new element.tag is the element name.attrs is a dictionarycontaining element attributes. Returns the opened element.
In addition, a customTreeBuilder object can provide thefollowing method:
Handles a doctype declaration.name is the doctype name.pubid isthe public identifier.system is the system identifier. This methoddoes not exist on the defaultTreeBuilder class.
New in version 3.2.
Element structure builder for XML source data, based on the expatparser.html are predefined HTML entities. This flag is not supported bythe current implementation.target is the target object. If omitted, thebuilder uses an instance of the standardTreeBuilder class.encoding[1] is optional. If given, the value overrides the encodingspecified in the XML file.
Finishes feeding data to the parser. Returns the result of calling theclose() method of thetarget passed during construction; by default,this is the toplevel document element.
Deprecated since version 3.2:Define theTreeBuilder.doctype() method on a custom TreeBuildertarget.
Feeds data to the parser.data is encoded data.
XMLParser.feed() callstarget‘sstart() methodfor each opening tag, itsend() method for each closing tag,and data is processed by methoddata().XMLParser.close()callstarget‘s methodclose().XMLParser can be used not only for building a tree structure.This is an example of counting the maximum depth of an XML file:
>>>fromxml.etree.ElementTreeimportXMLParser>>>classMaxDepth:# The target object of the parser...maxDepth=0...depth=0...defstart(self,tag,attrib):# Called for each opening tag....self.depth+=1...ifself.depth>self.maxDepth:...self.maxDepth=self.depth...defend(self,tag):# Called for each closing tag....self.depth-=1...defdata(self,data):...pass# We do not need to do anything with data....defclose(self):# Called when all data has been parsed....returnself.maxDepth...>>>target=MaxDepth()>>>parser=XMLParser(target=target)>>>exampleXml="""...<a>... <b>... </b>... <b>... <c>... <d>... </d>... </c>... </b>...</a>""">>>parser.feed(exampleXml)>>>parser.close()4
XML parse error, raised by the various parsing methods in this module whenparsing fails. The string representation of an instance of this exceptionwill contain a user-friendly error message. In addition, it will havethe following attributes available:
A numeric error code from the expat parser. See the documentation ofxml.parsers.expat for the list of error codes and their meanings.
A tuple ofline,column numbers, specifying where the error occurred.
Footnotes
| [1] | The encoding string included in XML output should conform to theappropriate standards. For example, “UTF-8” is valid, but “UTF8” isnot. Seehttp://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDeclandhttp://www.iana.org/assignments/character-sets. |
20.6.xml.dom — The Document Object Model API
Enter search terms or a module, class or function name.