Python 3 - przetwarzanie XML
XML to przenośny język open source, który umożliwia programistom tworzenie aplikacji, które mogą być odczytywane przez inne aplikacje, niezależnie od systemu operacyjnego i / lub języka programowania.
Co to jest XML?
Extensible Markup Language (XML) jest językiem znaczników, podobnie jak HTML czy SGML. Jest to zalecane przez konsorcjum World Wide Web i dostępne jako otwarty standard.
XML jest niezwykle przydatny do śledzenia małych i średnich ilości danych bez konieczności korzystania z sieci szkieletowej opartej na języku SQL.
Architektury i API parsera XML
Biblioteka standardowa Pythona zapewnia minimalny, ale przydatny zestaw interfejsów do pracy z XML.
Dwa najbardziej podstawowe i szeroko stosowane API do danych XML to interfejsy SAX i DOM.
Simple API for XML (SAX)- Tutaj rejestrujesz wywołania zwrotne dla interesujących zdarzeń, a następnie pozwalasz parserowi przejść przez dokument. Jest to przydatne, gdy dokumenty są duże lub masz ograniczenia pamięci, analizuje plik podczas odczytywania go z dysku, a cały plik nigdy nie jest zapisywany w pamięci.
Document Object Model (DOM) API - To jest zalecenie konsorcjum World Wide Web Consortium, w którym cały plik jest wczytywany do pamięci i przechowywany w formie hierarchicznej (opartej na drzewie), aby przedstawić wszystkie cechy dokumentu XML.
Oczywiście SAX nie może przetwarzać informacji tak szybko jak DOM podczas pracy z dużymi plikami. Z drugiej strony, używanie wyłącznie DOM może naprawdę zniszczyć twoje zasoby, zwłaszcza jeśli jest używane na wielu małych plikach.
SAX jest tylko do odczytu, podczas gdy DOM umożliwia zmiany w pliku XML. Ponieważ te dwa różne interfejsy API dosłownie się uzupełniają, nie ma powodu, dla którego nie można używać ich obu w dużych projektach.
We wszystkich naszych przykładach kodu XML jako danych wejściowych użyjmy prostego pliku XML movies.xml -
<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>
Parsowanie XML za pomocą SAX API
SAX to standardowy interfejs do analizowania XML sterowanego zdarzeniami. Parsowanie XML za pomocą SAX zazwyczaj wymaga utworzenia własnego ContentHandler'a przez podklasę xml.sax.ContentHandler.
Twój ContentHandler obsługuje określone znaczniki i atrybuty Twojego smaku (-ów) XML. Obiekt ContentHandler udostępnia metody do obsługi różnych zdarzeń analizy. Jego parser będący właścicielem wywołuje metody ContentHandler podczas analizowania pliku XML.
Metody startDocument i endDocument są wywoływane na początku i na końcu pliku XML. Znaki metody (tekst) są przekazywane jako dane znakowe pliku XML poprzez tekst parametru.
ContentHandler jest wywoływana na początku i na końcu każdego elementu. Jeśli parser nie jest w trybie przestrzeni nazw, wywoływane są metody startElement (tag, atrybuty) i endElement (tag) ; w przeciwnym razie wywoływane są odpowiednie metody startElementNS i endElementNS . W tym przypadku tag to znacznik elementu, a atrybuty to obiekt Attributes.
Oto inne ważne metody, które należy zrozumieć przed kontynuowaniem -
Metoda make_parser
Poniższa metoda tworzy nowy obiekt parsera i zwraca go. Utworzony obiekt parsera będzie pierwszego typu analizatora składni znalezionego przez system.
xml.sax.make_parser( [parser_list] )
Oto szczegóły parametrów -
parser_list - Opcjonalny argument składający się z listy parserów do użycia, z których wszystkie muszą implementować metodę make_parser.
Metoda analizy
Poniższa metoda tworzy parser SAX i używa go do analizowania dokumentu.
xml.sax.parse( xmlfile, contenthandler[, errorhandler])
Oto szczegóły parametrów -
xmlfile - To jest nazwa pliku XML do odczytu.
contenthandler - To musi być obiekt ContentHandler.
errorhandler - Jeśli określono, errorhandler musi być obiektem SAX ErrorHandler.
Metoda parseString
Jest jeszcze jedna metoda tworzenia parsera SAX i analizowania podanego XML string.
xml.sax.parseString(xmlstring, contenthandler[, errorhandler])
Oto szczegóły parametrów -
xmlstring - To jest nazwa ciągu XML do odczytu.
contenthandler - To musi być obiekt ContentHandler.
errorhandler - Jeśli określono, errorhandler musi być obiektem SAX ErrorHandler.
Przykład
#!/usr/bin/python3
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")
Wynik
Dałoby to następujący wynik -
*****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 scientific 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
Aby uzyskać szczegółowe informacje na temat dokumentacji API SAX, zapoznaj się ze standardowymi interfejsami API Python SAX .
Przetwarzanie XML za pomocą interfejsów API DOM
Document Object Model („DOM”) to wielojęzyczny interfejs API firmy World Wide Web Consortium (W3C) służący do uzyskiwania dostępu i modyfikowania dokumentów XML.
DOM jest niezwykle przydatny w aplikacjach o swobodnym dostępie. SAX pozwala na podgląd tylko jednego bitu dokumentu na raz. Jeśli patrzysz na jeden element SAX, nie masz dostępu do innego.
Oto najprostszy sposób na szybkie załadowanie dokumentu XML i utworzenie obiektu minidom przy użyciu modułu xml.dom. Obiekt minidom zapewnia prostą metodę parsera, która szybko tworzy drzewo DOM z pliku XML.
Przykładowa fraza wywołuje funkcję parse (file [, parser]) obiektu minidom w celu przeanalizowania pliku XML, wyznaczonego przez plik, do obiektu drzewa DOM.
Przykład
#!/usr/bin/python3
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)
Wynik
Dałoby to następujący wynik -
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 scientific 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
Aby uzyskać szczegółowe informacje na temat dokumentacji DOM API, zapoznaj się ze standardowymi interfejsami API języka Python DOM .