Python - XML-verwerking
XML is een draagbare, open source-taal waarmee programmeurs applicaties kunnen ontwikkelen die door andere applicaties kunnen worden gelezen, ongeacht het besturingssysteem en/of de ontwikkelingstaal.
Wat is XML?
De Extensible Markup Language (XML) is een opmaaktaal die veel lijkt op HTML of SGML. Dit wordt aanbevolen door het World Wide Web Consortium en is beschikbaar als open standaard.
XML is uitermate handig voor het bijhouden van kleine tot middelgrote hoeveelheden gegevens zonder dat een op SQL gebaseerde backbone nodig is.
XML-parserarchitecturen en API's
De Python-standaardbibliotheek biedt een minimale maar nuttige set interfaces om met XML te werken.
De twee meest elementaire en meest gebruikte API's voor XML-gegevens zijn de SAX- en DOM-interfaces.
-
Eenvoudige API voor XML (SAX) − Hier registreert u terugbelverzoeken voor interessante gebeurtenissen en laat u de parser vervolgens het document doorlopen. Dit is handig als uw documenten groot zijn of als u geheugenbeperkingen heeft, het bestand wordt geparseerd terwijl het van de schijf wordt gelezen en het hele bestand wordt nooit in het geheugen opgeslagen.
-
Document Object Model (DOM) API − Dit is een aanbeveling van het World Wide Web Consortium waarbij het hele bestand in het geheugen wordt gelezen en in een hiërarchische (op boomstructuur gebaseerde) vorm wordt opgeslagen om alle kenmerken van een XML-document weer te geven.
SAX kan informatie uiteraard niet zo snel verwerken als DOM bij het werken met grote bestanden. Aan de andere kant kan het uitsluitend gebruiken van DOM je bronnen echt vernietigen, vooral als het wordt gebruikt voor veel kleine bestanden.
SAX is alleen-lezen, terwijl DOM wijzigingen in het XML-bestand toestaat. Aangezien deze twee verschillende API's elkaar letterlijk aanvullen, is er geen reden waarom je ze niet allebei voor grote projecten zou kunnen gebruiken.
Laten we voor al onze XML-codevoorbeelden een eenvoudig XML-bestand gebruiken movies.xml als invoer −
<collection shelf="New Arrivals"> <movie title="Enemy Behind"> <type>War, Thriller</type> <format>DVD</format> <year>2003</year> <rating>PG</rating> <stars>10</stars> <description>Talk about a US-Japan war</description> </movie> <movie title="Transformers"> <type>Anime, Science Fiction</type> <format>DVD</format> <year>1989</year> <rating>R</rating> <stars>8</stars> <description>A schientific fiction</description> </movie> <movie title="Trigun"> <type>Anime, Action</type> <format>DVD</format> <episodes>4</episodes> <rating>PG</rating> <stars>10</stars> <description>Vash the Stampede!</description> </movie> <movie title="Ishtar"> <type>Comedy</type> <format>VHS</format> <rating>PG</rating> <stars>2</stars> <description>Viewable boredom</description> </movie> </collection>
XML ontleden met SAX API's
SAX is een standaardinterface voor gebeurtenisgestuurde XML-parsing. Voor het parseren van XML met SAX moet u over het algemeen uw eigen ContentHandler maken door xml.sax.ContentHandler te subclasseren.
Uw ContentHandler behandelt de specifieke tags en attributen van uw smaak(en) van XML. Een ContentHandler-object biedt methoden om verschillende parseergebeurtenissen af te handelen. De eigenaar van de parser roept ContentHandler-methoden aan terwijl het het XML-bestand ontleedt.
De methoden startDocument en endDocument worden aan het begin en het einde van het XML-bestand aangeroepen. De methode characters(text) worden karaktergegevens van het XML-bestand doorgegeven via de parametertekst.
De ContentHandler wordt aan het begin en einde van elk element aangeroepen. Als de parser niet in de naamruimtemodus staat, worden de methoden startElement(tag, attributes) en endElement(tag) worden genoemd; anders, de corresponderende methoden startElementNS en endElementNS worden genoemd. Hier is tag de elementtag en attributen is een Attributen-object.
Hier zijn andere belangrijke methoden die u moet begrijpen voordat u verder gaat −
De make_parser Methode
De volgende methode maakt een nieuw parser-object en retourneert het. Het gemaakte parserobject is van het eerste parsertype dat het systeem vindt.
xml.sax.make_parser( [parser_list] )
Hier is het detail van de parameters −
-
parser_list − Het optionele argument dat bestaat uit een lijst met te gebruiken parsers die allemaal de methode make_parser moeten implementeren.
De ontleding Methode
De volgende methode maakt een SAX-parser aan en gebruikt deze om een document te ontleden.
xml.sax.parse( xmlfile, contenthandler[, errorhandler])
Hier is het detail van de parameters −
-
xml-bestand − Dit is de naam van het XML-bestand waaruit moet worden gelezen.
-
contenthandler − Dit moet een ContentHandler-object zijn.
-
foutbehandelaar − Indien gespecificeerd, moet errorhandler een SAX ErrorHandler-object zijn.
De parseString Methode
Er is nog een methode om een SAX-parser te maken en de opgegeven XML-tekenreeks te ontleden .
xml.sax.parseString(xmlstring, contenthandler[, errorhandler])
Hier is het detail van de parameters −
-
xmlstring − Dit is de naam van de XML-tekenreeks waaruit moet worden gelezen.
-
contenthandler − Dit moet een ContentHandler-object zijn.
-
foutbehandelaar − Indien gespecificeerd, moet errorhandler een SAX ErrorHandler-object zijn.
Voorbeeld
#!/usr/bin/python import xml.sax class MovieHandler( xml.sax.ContentHandler ): def __init__(self): self.CurrentData = "" self.type = "" self.format = "" self.year = "" self.rating = "" self.stars = "" self.description = "" # Call when an element starts def startElement(self, tag, attributes): self.CurrentData = tag if tag == "movie": print "*****Movie*****" title = attributes["title"] print "Title:", title # Call when an elements ends def endElement(self, tag): if self.CurrentData == "type": print "Type:", self.type elif self.CurrentData == "format": print "Format:", self.format elif self.CurrentData == "year": print "Year:", self.year elif self.CurrentData == "rating": print "Rating:", self.rating elif self.CurrentData == "stars": print "Stars:", self.stars elif self.CurrentData == "description": print "Description:", self.description self.CurrentData = "" # Call when a character is read def characters(self, content): if self.CurrentData == "type": self.type = content elif self.CurrentData == "format": self.format = content elif self.CurrentData == "year": self.year = content elif self.CurrentData == "rating": self.rating = content elif self.CurrentData == "stars": self.stars = content elif self.CurrentData == "description": self.description = content if ( __name__ == "__main__"): # create an XMLReader parser = xml.sax.make_parser() # turn off namepsaces parser.setFeature(xml.sax.handler.feature_namespaces, 0) # override the default ContextHandler Handler = MovieHandler() parser.setContentHandler( Handler ) parser.parse("movies.xml")
Dit zou het volgende resultaat opleveren −
*****Movie***** Title: Enemy Behind Type: War, Thriller Format: DVD Year: 2003 Rating: PG Stars: 10 Description: Talk about a US-Japan war *****Movie***** Title: Transformers Type: Anime, Science Fiction Format: DVD Year: 1989 Rating: R Stars: 8 Description: A schientific fiction *****Movie***** Title: Trigun Type: Anime, Action Format: DVD Rating: PG Stars: 10 Description: Vash the Stampede! *****Movie***** Title: Ishtar Type: Comedy Format: VHS Rating: PG Stars: 2 Description: Viewable boredom
Raadpleeg de standaard Python SAX API's voor een volledig detail over SAX API-documentatie.
XML ontleden met DOM API's
Het Document Object Model ("DOM") is een meertalige API van het World Wide Web Consortium (W3C) voor het openen en wijzigen van XML-documenten.
De DOM is uitermate handig voor toepassingen met willekeurige toegang. Met SAX kunt u slechts één bit van het document tegelijk bekijken. Als je naar het ene SAX-element kijkt, heb je geen toegang tot het andere.
Dit is de gemakkelijkste manier om snel een XML-document te laden en een minidom-object te maken met behulp van de xml.dom-module. Het minidom-object biedt een eenvoudige parsermethode die snel een DOM-boom maakt van het XML-bestand.
De voorbeeldzin roept de functie parse( file [,parser] ) van het minidom-object aan om het XML-bestand dat door bestand is aangewezen, te ontleden in een DOM-boomobject.
#!/usr/bin/python from xml.dom.minidom import parse import xml.dom.minidom # Open XML document using minidom parser DOMTree = xml.dom.minidom.parse("movies.xml") collection = DOMTree.documentElement if collection.hasAttribute("shelf"): print "Root element : %s" % collection.getAttribute("shelf") # Get all the movies in the collection movies = collection.getElementsByTagName("movie") # Print detail of each movie. for movie in movies: print "*****Movie*****" if movie.hasAttribute("title"): print "Title: %s" % movie.getAttribute("title") type = movie.getElementsByTagName('type')[0] print "Type: %s" % type.childNodes[0].data format = movie.getElementsByTagName('format')[0] print "Format: %s" % format.childNodes[0].data rating = movie.getElementsByTagName('rating')[0] print "Rating: %s" % rating.childNodes[0].data description = movie.getElementsByTagName('description')[0] print "Description: %s" % description.childNodes[0].data
Dit zou het volgende resultaat opleveren −
Root element : New Arrivals *****Movie***** Title: Enemy Behind Type: War, Thriller Format: DVD Rating: PG Description: Talk about a US-Japan war *****Movie***** Title: Transformers Type: Anime, Science Fiction Format: DVD Rating: R Description: A schientific fiction *****Movie***** Title: Trigun Type: Anime, Action Format: DVD Rating: PG Description: Vash the Stampede! *****Movie***** Title: Ishtar Type: Comedy Format: VHS Rating: PG Description: Viewable boredom
Raadpleeg de standaard Python DOM API's voor een volledig detail over DOM API-documentatie.
Python