Przeszukiwanie dokumentów XML przy pomocy XPath
Dokumenty XML są standardem przechowywania i przekazywania
danych. Xpath natomiast jest jedną z podstawowych metod przeszukiwania XMLi. Jak więc w Pythonie przeszukiwać xmle?
Python posiada w bibliotece standardowej parser XML - moduł xml. Jednak moduł ten ma ograniczone wsparcie dla XPath (zobacz xpath support na docs.python.org). Bogatsze wsparcie dla XPath zapewnia biblioteka lxml, oparta na libxml2 i libxslt - dobrze rozwiniętych i dostępnych na wiele platform bibliotek. lxml można łatwo zainstalować przy pomocy pip-a, jest wśród standardowych pakietów anacondy, a ze względu na zależności często jest zainstalowany także na linuxowych systemach (zależy od niego np. Inkscape i Cinnamon).
Poniższy program, kompatybilny z Python 3, przedstawia przykłady użycia lxml do parsowania XML z wykorzystaniem XPath.
Python posiada w bibliotece standardowej parser XML - moduł xml. Jednak moduł ten ma ograniczone wsparcie dla XPath (zobacz xpath support na docs.python.org). Bogatsze wsparcie dla XPath zapewnia biblioteka lxml, oparta na libxml2 i libxslt - dobrze rozwiniętych i dostępnych na wiele platform bibliotek. lxml można łatwo zainstalować przy pomocy pip-a, jest wśród standardowych pakietów anacondy, a ze względu na zależności często jest zainstalowany także na linuxowych systemach (zależy od niego np. Inkscape i Cinnamon).
Poniższy program, kompatybilny z Python 3, przedstawia przykłady użycia lxml do parsowania XML z wykorzystaniem XPath.
'''przykladowy program parsujacy XMLe''' from lxml import etree # przykladowy xml wczytany bezposrednio z lancucha bajtow. xml = etree.fromstring(b'''<?xml version="1.0" encoding="UTF-8"?> <ksiazki> <ksiazka> <tytul lang="pl">Pan Tadeusz</tytul> <autor>A. Mickiewicz</autor> <rok>2012</rok> <cena>31.99</cena> </ksiazka> <ksiazka> <tytul lang="pl">Antygona</tytul> <autor>Sofokles</autor> <rok>2006</rok> <cena>5.99</cena> </ksiazka> <f:ksiazka xmlns:f="https://wrobelmaciek.blogspot.com/ksiazki"> <f:tytul lang="pl">Emocjonalne wampiry w pracy</f:tytul> <f:autor>A. B. Bernstein</f:autor> <f:rok>2014</f:rok> <f:cena>37.90</f:cena> </f:ksiazka> </ksiazki> ''') #metoda xpath zwraca liste elementow spelniajacych kryteria #elementy sa objektami, mozna odczytac ich tekst, wziac przodka, #atrybuty itd. print('autorzy ksiazek i jezyk tytulu') for el in xml.xpath('.//autor'): print('{0}:{1}'.format(el.text, el.getparent().find('tytul').get('lang'), )) #lxml obsluguje tez bardziej zlozone zapytania print('tytuly ksiazek zaczynajace sie na A:') print('\n'.join([x.text for x in xml.xpath('.//*[name()="tytul" and starts-with(text(),"A")]')])) #lxml obsluguje tez przestrzenie nazw (namespaces) print('''autorzy o nazwiskach zaczynajacych sie na A, niezależnie od przestrzeni nazw:''') print('\n'.join(['%s %s'%(x.tag,x.text,) for x in xml.xpath('.//*[local-name()="autor" and starts-with(text(),"A")]')])) print('''ksiazki o autorach zaczynajacych sie na A, z przestrzeni nazw {https://wrobelmaciek.blogspot.com/ksiazki}:''') print('\n'.join(['%s %s'%(x.tag,x.text,) for x in xml.xpath('.//g:autor[starts-with(text(),"A")]', namespaces={'g':'https://wrobelmaciek.blogspot.com/ksiazki'})])) #jesli nie potrzebujemy zlozonych zapytan, mozemy uzyc tez findall #kompatybilnego z xml.ElementTree z biblioteki standardowej pythona print('autorzy ksiazek i jezyk tytulu - findall') for el in xml.findall('.//autor'): print('{0}:{1}'.format(el.text, el.getparent().find('tytul').get('lang'), )) #findall obsluguje tylko najprostsze zapytania XPath try: print('to nie zadziala') for el in xml.findall('.//*[name()="autor"]'): print('{0}:{1}'.format(el.text, el.getparent().find('tytul').get('lang'), )) except SyntaxError: print('zbyt skomplikowany predykat')