El format XML s'ha introduït en tots els camps (inclosos la traducció) per diversos motius, però en podem destacar uns pocs:
En aquesta unitat veurem alguns exemples senzills i el lector podrà crear-se les seves pròpies aplicacions modificant els exemples que exposem. També es pot trobar molta més informació sobre Python i XML en els següents enllaços:
Farem servir diverses tècniques per llegir i obtenir informació d'arxius XML:
En tota aquesta unitat farem servir com a arxiu XML un que representa una base de dades de CDs de música. El podeu trobar adjunt en aquesta plana . Aprofiteu per obrir-lo amb un editor de textos. Aquest arxiu el presentem en tres versions:
Per a cada programa que presenteu serà interessant observar si l'estratègia que hem fet servir funciona correctament per a les tres versions d'aquest arxiu.
D'aquesta unitat disposeu dels següents arxius:
Els arxius XML es poden tractar amb funcions estàndar de cadena com en el programa-10-1.py.
import codecs
entrada=codecs.open("catalog.xml","r",encoding="utf-8")
sortida=codecs.open("catalog.txt","w",encoding="utf-8")
artist=""
title=""
year=""
for linia in entrada:
linia=linia.rstrip().lstrip()
if linia.startswith("</cd>"):
if not artist=="" and not title=="" and not year=="":
cadena=artist+"\t"+title+"\t"+year
print(cadena)
sortida.write(cadena+"\n")
if linia.startswith("<title>") and linia.endswith("</title>"):
title=linia[7:-8]
elif linia.startswith("<artist>") and linia.endswith("</artist>"):
artist=linia[8:-9]
elif linia.startswith("<year>") and linia.endswith("</year>"):
year=linia[6:-7]
Si ens fixem, en aquest codi veurem que només es fan servir funcions de cadena estàndar com startswith() i endswith(), per exemple. Si l'executem, veurem que funciona correctament i que a la sortida ens dóna la informació d'artista, títol i any.
Bob Dylan Empire Burlesque 1985
Bonnie Tyler Hide your heart 1988
Dolly Parton Greatest Hits 1982
Gary Moore Still got the blues 1990
Aquesta estratègia pot ser vàlida, però es basa massa en la disposició física de les marques i la informació en el document. Proveu ara si aquest programa funciona bé per a catalog-mod.txt i catalog-mod2.txt.
Per evitar el problema de la dependència de la disposició de la informació, podem fer ús d'expressions regulars, com en el següent programa (programa-10-2.py)
import codecs
import re
entrada=codecs.open("catalog.xml","r",encoding="utf-8")
sortida=codecs.open("catalog.txt","w",encoding="utf-8")
artist=""
title=""
year=""
for linia in entrada:
linia=linia.rstrip().lstrip()
if linia.startswith("</cd>"):
if not artist=="" and not title=="" and not year=="":
cadena=artist+"\t"+title+"\t"+year
print(cadena)
sortida.write(cadena+"\n")
else:
m_title = re.search('<title>(.+?)</title>', linia)
if m_title:
title = m_title.group(1)
m_artist = re.search('<artist>(.+?)</artist>', linia)
if m_artist:
artist = m_artist.group(1)
m_year = re.search('<year>(.+?)</year>', linia)
if m_year:
year = m_year.group(1)
Proveu d'executar el programa amb els arxius catalog modificats. Els pot tractar tots?
xml2dict ens permet tractar arxius XML d'una manera molt fàcil, ja que converteix l'arxius XML en una estructura de dades de tipus diccionari. En el programa-10-3.py podem observar com fer servir aquesta llibreria.
import xmltodict
xml=open('catalog.xml')
xmldict = xmltodict.parse(xml.read())
for cd in xmldict["catalog"]["cd"]:
print(cd["artist"],cd["title"],cd["year"])
Proveu amb totes les modificacions de l'arxiu catalog i observeu si és capaç de processar-lo correctament.
Disposem d'una sèrie de llibreries que ens faciliten molt la lectura d'arxius XML. Una d'elles és xml.etree.ElementTree. Per observar com funciona, executarem el programa-10-4.py i observarem la sortida:
import xml.etree.ElementTree as etree
for event, elem in etree.iterparse("catalog.xml",events=("start", "end")):
print(event,elem,elem.tag,elem.attrib)
La llibreria és capaç de detectar quan hi ha un event (i hem seleccionat el principi (start) i el final (end)), el element afectat, l'etiqueta de l'element i l'atribut de l'element. En aquest programa de prova simplement escrivim aquesta informació:
start <Element 'catalog' at 0x7f456b5c3728> catalog {}
start <Element 'cd' at 0x7f4569d999f8> cd {'id': '1'}
start <Element 'title' at 0x7f4569d3c2c8> title {}
end <Element 'title' at 0x7f4569d3c2c8> title {}
start <Element 'artist' at 0x7f4569d3c318> artist {}
end <Element 'artist' at 0x7f4569d3c318> artist {}
Amb aquesta informació, podem fer un programa que llegeixi l'arxiu (programa-10.5.py):
import xml.etree.ElementTree as etree
import codecs
artist=""
title=""
year=""
sortida=codecs.open("catalog.txt","w",encoding="utf-8")
for event, elem in etree.iterparse("catalog.xml",events=("start", "end")):
if event=="end" and elem.tag=="cd":
cadena=artist+"\t"+title+"\t"+year
print(cadena)
sortida.write(cadena+"\n")
artist=""
title=""
year=""
if event=="end" and elem.tag=="title":
title="".join(elem.itertext()).lstrip().rstrip()
if event=="end" and elem.tag=="artist":
artist="".join(elem.itertext()).lstrip().rstrip()
if event=="end" and elem.tag=="year":
year="".join(elem.itertext()).lstrip().rstrip()
Comproveu que aquest programa funciona també bé amb el catalog modificat.