Mam wiele wierszy w bazie danych zawierającej XML i próbuję napisać skrypt w języku Python, aby policzyć wystąpienia określonego atrybutu węzła.
Moje drzewo wygląda następująco:
<foo>
<bar>
<type foobar="1"/>
<type foobar="2"/>
</bar>
</foo>
Jak mogę uzyskać dostęp do atrybutów "1"
i "2"
kodu XML za pomocą Pythona?
Odpowiedzi:
Sugeruję
ElementTree
. Istnieją inne kompatybilne implementacje tego samego API, jaklxml
icElementTree
w samej bibliotece standardowej Pythona; ale w tym kontekście dodają przede wszystkim jeszcze większą szybkość - łatwość programowania zależy od API, któreElementTree
definiuje.Najpierw zbuduj instancję Element
root
na podstawie XML, np. Za pomocą funkcji XML lub parsując plik za pomocą czegoś takiego:Lub dowolny z wielu innych sposobów pokazanych na
ElementTree
. Następnie zrób coś takiego:I podobne, zwykle dość proste, wzory kodu.
źródło
lxml
dodaje więcej niż prędkości. Zapewnia łatwy dostęp do informacji, takich jak węzeł nadrzędny, numer wiersza w źródle XML itp., Które mogą być bardzo przydatne w kilku scenariuszach.Warning The xml.etree.ElementTree module is not secure against maliciously constructed data. If you need to parse untrusted or unauthenticated data see XML vulnerabilities.
minidom
jest najszybszy i całkiem prosty.XML:
Pyton:
Wynik:
źródło
item
bezpośrednio z najwyższego poziomu dokumentu? czy nie byłoby czystsze, gdybyś podał mu ścieżkę (data->items
)? bo co gdybyś też miałdata->secondSetOfItems
te same węzłyitem
i chciałbyś wymienić tylko jeden z dwóch zestawówitem
?Możesz użyć BeautifulSoup :
źródło
BeautifulStoneSoup
. Wystarczy użyćBeautifulSoup(source_xml, features="xml")
ElementTree
, niestety nie można go przeanalizować, chyba że dostosuję źródło w niektórych miejscach, aleBeautifulSoup
działało od razu bez żadnych zmian!Istnieje wiele opcji. cElementTree wygląda doskonale, jeśli problemem jest szybkość i zużycie pamięci. Ma bardzo mały narzut w porównaniu do zwykłego odczytu pliku za pomocą
readlines
.Odpowiednie wskaźniki można znaleźć w poniższej tabeli, skopiowanej ze strony internetowej cElementTree :
Jak wskazał @jfs ,
cElementTree
jest dostarczany w pakiecie z Pythonem:from xml.etree import cElementTree as ElementTree
.from xml.etree import ElementTree
(przyspieszona wersja C jest używana automatycznie).źródło
from xml.etree import cElementTree as ElementTree
. W Pythonie 3:from xml.etree import ElementTree
(przyspieszona wersja C jest używana automatycznie)ElementTree
dane zadanie. W przypadku dokumentów, które mieszczą się w pamięci, jest o wiele łatwiejszy w użyciuminidom
i działa dobrze w przypadku mniejszych dokumentów XML.Dla uproszczenia sugeruję xmltodict .
Analizuje twój XML do OrDERDict;
źródło
result["foo"]["bar"]["type"]
znajduje się lista wszystkich<type>
elementów, więc nadal działa (chociaż struktura może być nieco nieoczekiwana).Plik lxml.objectify jest naprawdę prosty.
Biorąc przykładowy tekst:
Wynik:
źródło
count
przechowuje liczniki każdego elementu w słowniku z domyślnymi kluczami, więc nie musisz sprawdzać członkostwa. Możesz także spróbować spojrzećcollections.Counter
.Python ma interfejs do analizatora XML expat.
To parser nie sprawdzający poprawności, więc zły kod XML nie zostanie przechwycony. Ale jeśli wiesz, że plik jest poprawny, to jest całkiem niezły i prawdopodobnie otrzymasz dokładne informacje, których potrzebujesz, a resztę możesz odrzucić w locie.
źródło
Mogę zaproponować declxml .
Pełne ujawnienie: Napisałem tę bibliotekę, ponieważ szukałem sposobu na konwersję między strukturami danych XML i Python bez konieczności pisania dziesiątek wierszy bezwzględnego parsowania / serializacji kodu za pomocą ElementTree.
Za pomocą declxml używasz procesorów do deklaratywnego definiowania struktury dokumentu XML oraz sposobu mapowania między strukturami danych XML i Python. Procesory są używane zarówno do serializacji i parsowania, jak i do podstawowego poziomu sprawdzania poprawności.
Analizowanie struktur danych w języku Python jest proste:
Co daje wynik:
Możesz także użyć tego samego procesora do serializacji danych do formatu XML
Który daje następujący wynik
Jeśli chcesz pracować z obiektami zamiast ze słownikami, możesz zdefiniować procesory do przekształcania danych do i z obiektów.
Który daje następujący wynik
źródło
Aby dodać kolejną możliwość, możesz użyć rozplątania , ponieważ jest to prosta biblioteka obiektów xml-to-python. Oto przykład:
Instalacja:
Stosowanie:
Twój plik XML (nieco zmieniony):
Dostęp do atrybutów za pomocą
untangle
:Dane wyjściowe będą:
Więcej informacji o rozplątywaniu można znaleźć w „ rozplątywaniu ”.
Ponadto, jeśli jesteś ciekawy, możesz znaleźć listę narzędzi do pracy z XML i Python w „ Python and XML ”. Przekonasz się również, że najczęściej spotykane były poprzednie odpowiedzi.
źródło
Tutaj bardzo prosty, ale skuteczny kod używający
cElementTree
.Pochodzi z „ parsowania xml Pythona ”.
źródło
XML:
Kod Python:
Wynik:
źródło
Spowoduje to wydrukowanie wartości
foobar
atrybutu.źródło
xml.etree.ElementTree vs. lxml
Oto niektóre zalety dwóch najczęściej używanych bibliotek, które chciałbym poznać, zanim dokonam wyboru między nimi.
xml.etree.ElementTree:
lxml
standalone="no"
?.node
.sourceline
pozwala łatwo uzyskać linię używanego elementu XML.źródło
Uważam, że Python xml.dom i xml.dom.minidom są dość łatwe. Pamiętaj, że DOM nie nadaje się do dużych ilości XML, ale jeśli twoje dane wejściowe są dość małe, to będzie działać dobrze.
źródło
Jeśli używasz , nie musisz używać interfejsu API specyficznego dla lib
python-benedict
. Wystarczy zainicjować nowe wystąpienie z pliku XML i łatwo nim zarządzać, ponieważ jest todict
podklasa.Instalacja jest łatwa:
pip install python-benedict
Wspiera i normalizuje I / O operacje z wieloma formatami:
Base64
,CSV
,JSON
,TOML
,XML
,YAML
iquery-string
.Jest dobrze przetestowany i otwarty na GitHub .
źródło
źródło
Jeśli źródłem jest plik xml, powiedz tak jak w tym przykładzie
możesz wypróbować następujący kod
Wyjście byłoby
źródło