""xml parsingsax is callback-based api for intercepting parser events ""import xml saxxml sax handlerpprint class bookhandler(xml sax handler contenthandler)def __init__(self)self intitle false self mapping {def startelement(selfnameattributes)if name ="book"self buffer "self isbn attributes["isbn"elif name ="title"self intitle true handle xml parser events state machine model on start book tag save isbn for dict key on start title tag save title text to follow def characters(selfdata)if self intitleself buffer +data on text within tag save text if in title def endelement(selfname)if name ="title"self intitle false self mapping[self isbnself buffer on end title tag store title text in dict parser xml sax make_parser(handler bookhandler(parser setcontenthandler(handlerparser parse('books xml'pprint pprint(handler mappingthe sax model is efficientbut it is potentially confusing at first glancebecause the class must keep track of where the parse currently is using state information for examplewhen the title tag is first detectedwe set state flag and initialize bufferas each character within the title tag is parsedwe append it to the buffer until the ending portion of the title tag is encountered the net effect saves the title tag' content as string this model is simplebut can be complex to managein cases of potentially arbitrary nestingfor instancestate information may need to be stacked as the class receives callbacks for nested tags to kick off the parsewe make parser objectset its handler to an instance of our classand start the parseas python scans the xml fileour class' methods are called automatically as components are encountered when the parse is completewe use the python pprint module to display the result again--the mapping dictionary object attached to our handler the result is the mostly the same this timebut notice that the "&escape sequence is properly un-escaped now--sax performs xml parsingnot text matching text and language