Python kullanılarak XML dosyaları nasıl ayrıştırılır?

Python kullanılarak XML dosyaları nasıl ayrıştırılır?

Myntra'da Instamart ve gardırop alışverişi yoluyla yiyecek siparişi vermekten MakemyTrip'te tatil rezervasyonu yapmaya kadar, web siteleri bu on yılda vazgeçilmez hale geldi! Bu web sitelerinin bilgileri müşterilere kolayca yorumlanabilir bir şekilde nasıl gösterdiğini ve ayrıca arka uçtaki verileri nasıl işleyip bunlarla etkileşime girdiğini hiç merak ettiniz mi?

Bu boşluğu kapatan, hem makine dili hem de insanlar tarafından yorumlanabilen belirli dosya biçimleri vardır. Genişletilebilir Biçimlendirme Dili'nin kısaltması olan XML, yaygın olarak kullanılan bir biçimdir.

XML dosyaları nedir ve bunları nasıl kullanırız?

XML dosyaları, istemciler ve sunucular arasında veri depolamak ve taşımak için kullanılır. Verileri, etiketler, nitelikler ve değerler aracılığıyla yapılandırılmış bir biçimde tanımlamamızı sağlar. XML'in ana avantajlarından biri esnekliğidir. Verileri birçok formatta temsil etmek için kullanılabilir ve yeni kullanımlara kolayca uyarlanabilir. Bu, onu web servisleri, veri alışverişi ve yapılandırma dosyaları gibi uygulamalar için popüler bir seçim haline getirir. Bu makalede, pratik bir örnekle bir XML dosyasını ayrıştırmak için sizi python'daki farklı yöntemlere götüreceğim.


XML Ayrıştırmayı otomatikleştirmek mi arıyorsunuz? Nanonets'in otomatikleştirilmiş iş akışlarını deneyin. Ücretsiz denemenizi şimdi başlatın.


XML dosyalarının yapısını anlama

XML dosyalarının nasıl ayrıştırılacağına ilişkin ayrıntılara girmeden önce, bir XML belgesinin farklı bölümlerini anlayalım. XML'de bir eleman yapılandırılmış bir bilgi parçasını temsil eden bir belgenin temel yapı taşıdır. Elemanın içeriği, her zaman aşağıda gösterildiği gibi bir açılış etiketi ile bir kapanış etiketi arasına yerleştirilmelidir.

Harry Potter ve Felsefe Taşı

Bir şirket tarafından sunulan farklı tur paketlerinin ayrıntılarını içeren “travel_pckgs.xml” adlı bir örnek dosya kullanacağım. Netlik için blog boyunca aynı dosyayı kullanmaya devam edeceğim.

<?xml version="1.0"?>
<travelPackages>
<package id='Paris vacation'>
<description>Experience the magnificent beauty of Paris and the french culture.</description>
<destination>Paris, France</destination>
<price>3000</price>
<duration>7</duration>
<payment>
<EMIoption>yes</EMIoption>
<refund>yes</refund>
</payment>
</package>
<package id='Hawaii Adventure'>
<description>Embark on an exciting adventure in Hawaii beaches!
</description>
<destination>Hawaii, USA</destination>
<price>4000</price>
<duration>10</duration>
<payment>
<EMIoption>no</EMIoption>
<refund>no</refund>
</payment>
</package>
<package id='Italian Getaway'>
<description>Indulge in the beauty and charm of Italy and get an all-
inclusive authentic Italian food tour!</description>
<destination>Italy</destination>
<price>2000</price>
<duration>8</duration>
<payment>
<EMIoption>yes</EMIoption>
<refund>no</refund>
</payment>
</package>
<package id='Andaman Island Retreat'>
<description>Experience the beauty of Island beaches,inclusive scuba
diving and Night kayaking through mangroves.</description>
<destination>Andaman and Nicobar Islands</destination>
<price>800</price>
<duration>8</duration>
<payment>
<EMIoption>no</EMIoption>
<refund>yes</refund>
</payment>
</package>
</travelPackages>

Dosya, bir acente tarafından sağlanan varış noktası, açıklama, fiyat ve ödeme seçenekleriyle birlikte 4 tur paketinin verilerini içerir. Yukarıdaki XML'in farklı bölümlerinin dökümüne bakalım:

  • Kök Öğe: En üst seviyedeki eleman, kök olarak anılır, bu da bizim dosyamızda Diğer tüm unsurları içerir (sunulan çeşitli turlar)
  • Özellik: 'id', her birinin özniteliğidir dosyamızdaki eleman. Özniteliğin her öğe için benzersiz değerlere ("Paris tatili", "Hawaii Macerası" vb.) sahip olması gerektiğini unutmayın. Nitelik ve değeri, görebileceğiniz gibi genellikle başlangıç ​​etiketinin içinde belirtilir.
  • Alt Öğeler: Kökün içine sarılmış elemanlar alt elemanlardır. Bizim durumumuzda, tüm   etiketler, her biri bir tur paketiyle ilgili ayrıntıları saklayan alt öğelerdir.
  • Alt Öğeler: Bir alt öğe, yapısında daha fazla alt öğeye sahip olabilir. bu alt öğenin alt öğeleri var , , , ve . XML'in avantajı, iç içe geçmiş birden çok öğe aracılığıyla hiyerarşik bilgileri depolamanıza izin vermesidir. bu alt öğe ayrıca alt öğelere sahiptir Ve, belirli bir paketin 'EMI ile ödeme' ve geri ödeme seçeneklerine sahip olup olmadığını gösterir.

İpucu: Bunu kullanarak net bir anlayış elde etmek için XML dosyasının bir Ağaç görünümünü oluşturabilirsiniz. araç. XML dosyamızın hiyerarşik ağaç görünümüne göz atın!

Python kullanarak XML dosyaları nasıl ayrıştırılır? PlatoBlockchain Veri Zekası. Dikey Arama. Ai.

Harika! Bu alanlarda saklanan verileri okumak, web sitesi için gerektiği gibi aramak, güncellemek ve değişiklikler yapmak istiyoruz, değil mi? Bu, XML verilerinin parçalara ayrıldığı ve farklı bölümlerin tanımlandığı ayrıştırma olarak adlandırılır.

Python'da bir XML dosyasını farklı kitaplıklarla ayrıştırmanın birden çok yolu vardır. İlk yönteme geçelim!


XML dosyalarını ayrıştırmak için Nanonets'i deneyin. Ücretsiz denemenizi herhangi bir kredi kartı bilgisi olmadan başlatın.


XML dosyalarını ayrıştırmak için Mini DOM'u kullanma

XML dosyalarını temsil etmek için standart bir API olan DOM (Belge Nesne Modeli) ile karşılaşacağınızdan eminim. Mini DOM, DOM'u minimum düzeyde uygulayan dahili bir python modülüdür.  

Mini DOM nasıl çalışır?

Girdi XML dosyasını belleğe yükleyerek öğeleri, nitelikleri ve metin içeriğini depolamak için ağaç benzeri bir yapı olan "DOM Ağacı" oluşturur. XML dosyaları da doğası gereği hiyerarşik ağaç yapısına sahip olduğundan, bu yöntem bilgide gezinmek ve bilgi almak için uygundur.

Aşağıdaki kod ile paketi nasıl içe aktaracağımızı görelim. XML dosyasını kullanarak ayrıştırabilirsiniz. xml.dom.minidom.parse() işlev ve ayrıca kök öğeyi alın.

import xml.dom.minidom
# parse the XML file
xml_doc = xml.dom.minidom.parse('travel_pckgs.xml')
# get the root element
root = xml_doc.documentElement
print('Root is',root)

Yukarıdaki kod için aldığım çıktı:

>> Root is <DOM Element: travelPackages at 0x7f05824a0280>

Diyelim ki her paketin yerini, süresini ve fiyatını yazdırmak istiyorum.  

The getAttribute() işlevi, bir öğenin özniteliğinin değerini almak için kullanılabilir.

Belirli bir etiket altındaki tüm öğelere erişmek istiyorsanız, getElementsByTagName()  yöntemini seçin ve etiketi girdi olarak sağlayın. En iyi yanı, getElementsByTagName() öğesinin iç içe geçmiş öğeleri çıkarmak için yinelemeli olarak kullanılabilmesidir.

# get all the package elements
packages = xml_doc.getElementsByTagName('package')
# loop through the packages and extract the data
for package in packages:
package_id = package.getAttribute('id')
description = package.getElementsByTagName('description')[0].childNodes[0].data
price = package.getElementsByTagName('price')[0].childNodes[0].data
duration = package.getElementsByTagName('duration')[0].childNodes[0].data
print('Package ID:', package_id)
print('Description:', description)
print('Price:', price)

Yukarıdaki kodun çıktısı, çıkarılan ve yazdırılan her paketin kimliği, açıklama metni ve fiyat değerleri ile burada gösterilir.

Package ID: Paris vacation
Description: Experience the magnificent beauty of Paris and the french culture.
Price: 3000
Package ID: Hawaii Adventure
Description: Embark on an exciting adventure in Hawaii beaches!
Price: 4000
Package ID: Italian Getaway
Description: Indulge in the beauty and charm of Italy and get an all-inclusive authentic Italian food tour!
Price: 2000
Package ID: Andaman Island Retreat
Description: Experience the beauty of Island beaches,inclusive scuba
diving and Night kayaking through mangroves.
Price: 800

Minidom ayrıştırıcı ayrıca DOM ağacını bir öğeden üst öğeye, ilk alt öğeye, son alt öğeye vb. İlk çocuğuna erişebilirsiniz. öğesini kullanan öğe ilk çocuk bağlanmak. Ayıklanan alt öğenin düğüm adı ve değeri de yazdırılabilir. düğümAdı ve düğümDeğeri aşağıda gösterildiği gibi nitelikler.

# get the first package element
paris_package = xml_doc.getElementsByTagName('package')[0]
# get the first child of the package element
first_child = paris_package.firstChild
#print(first_child)
>>
<DOM Element: description at 0x7f2e4800d9d0>
Node Name: description
Node Value: None

"Açıklama"nın ilk alt öğe olduğunu doğrulayabilirsiniz. . adlı bir öznitelik de vardır. alt düğümler bu, geçerli düğümde bulunan tüm alt öğeleri döndürür. Aşağıdaki örneği ve çıktısını kontrol edin.

child_elements=paris_package.childNodes
print(child_elements)
>>
[<DOM Element: description at 0x7f057938e940>, <DOM Element: destination at 0x7f057938e9d0>, <DOM Element: price at 0x7f057938ea60>, <DOM Element: duration at 0x7f057938eaf0>, <DOM Element: payment at 0x7f057938eb80>]

Buna benzer olarak minidom, parentNode, lastChild nextSibling, vb. gibi daha fazla geçiş yolu sağlar. Kütüphanenin mevcut tüm fonksiyonlarını kontrol edebilirsiniz. okuyun.

Ancak, bu yöntemin en büyük dezavantajı, tüm dosya belleğe yüklendiği için pahalı bellek kullanımıdır. Büyük dosyalar için minidom kullanmak pratik değildir. 


Nanonet'leri ayrıştıran XML'i otomatikleştirin. Ücretsiz denemenizi bugün başlatın. Kredi kartı gerekmez.


XML dosyalarını ayrıştırmak için ElementTree Library'yi kullanma

ElementTree, XML dosyalarını okumak, işlemek ve değiştirmek için birçok işlev sağlayan, yaygın olarak kullanılan yerleşik bir python ayrıştırıcısıdır. Bu ayrıştırıcı, verileri hiyerarşik bir biçimde depolamak için ağaç benzeri bir yapı oluşturur.

Kitaplığı içe aktararak ve XML dosyamızın parse() işlevini çağırarak başlayalım. Girdi dosyasını bir dize biçiminde de sağlayabilir ve dizeden() işlev. Ayrıştırılmış bir ağacı başlattıktan sonra, kök al () aşağıda gösterildiği gibi kök etiketi almak için işlev.

import xml.etree.ElementTree as ET
tree = ET.parse('travel_pckgs.xml')
#calling the root element
root = tree.getroot()
print("Root is",root)
Output:
>>
Root is <Element 'travelPackages' at 0x7f93531eaa40>

'travelPackages' kök etiketi çıkarıldı!

Şimdi diyelim ki istiyoruz erişim Tüm ilk çocuk etiketleri kökün. Basit bir for döngüsü kullanabilir ve bunun üzerinde yineleyerek hedef, fiyat gibi alt etiketleri yazdırabiliriz… Açıklamanın açılış etiketi içinde bir nitelik değeri belirtmiş olsaydık, parantezlerin boş olmayacağını unutmayın. Aşağıdaki snippet'e göz atın!

for x in root[0]:
print(x.tag, x.attrib)
Output:
>>
description {}
destination {}
price {}
duration {}
payment {}

Alternatif olarak, yineleme() işlevi, ağacın tamamında ilgilendiğiniz herhangi bir öğeyi bulmanıza yardımcı olabilir. Bunu, dosyamızdaki her bir tur paketinin açıklamalarını çıkarmak için kullanalım. kullanmayı unutmayın 'Metin' bir öğenin metnini çıkarmak için öznitelik.

For x in root.iter('description'):
print(x.text)
Output:
>> "Experience the magnificent beauty of Paris and the french culture." "Embark on an exciting adventure in Hawaii beaches!" "Indulge in the beauty and charm of Italy and get an all-inclusive authentic Italian food tour!" "Experience the beauty of Island beaches,inclusive scuba diving and Night kayaking through mangroves.

ElementTree'yi kullanırken, temel for döngüsü, alt öğelere erişmek için oldukça güçlüdür. Nasıl olduğunu görelim.

Bir for döngüsü ile XML dosyalarını ayrıştırma

Aşağıda gösterildiği gibi öznitelikleri çıkararak, bir for döngüsü ile alt öğeler arasında kolayca yineleme yapabilirsiniz.

for tour in root:
print(tour.attrib)
Output:
>>
{'id': 'Paris vacation'}
{'id': 'Hawaii Adventure'}
{'id': 'Italian Getaway'}
{'id': 'Andaman Island Retreat'}

ElementTee, karmaşık sorgulama ve filtrelemeyi işlemek için şu özelliklere sahiptir: hepsini bul() yöntem. Bu yöntem, parametre olarak iletilen etiketin tüm alt öğelerine erişmenizi sağlar. Diyelim ki 4000 $'ın altındaki tur paketlerini öğrenmek istiyorsunuz ve ayrıca EMIoption 'evet' seçeneğiniz var. Snippet'i kontrol edin.

for package in root.findall('package'):
price = int(package.find('price').text)
refund = package.find('payment/refund').text.strip("'")
if price < 4000 and refund == 'yes':
print(package.attrib['id'])

Temel olarak paketleri root.findall('package') aracılığıyla yineliyoruz ve ardından fiyatı ve geri ödemeyi şu şekilde alıyoruz: bul () yöntem. Bundan sonra, kısıtlamaları kontrol ediyoruz ve aşağıda yazdırılan nitelikli paketleri filtreliyoruz.

Çıktı:

>>

paris tatili

Andaman Adası Tatili

MiniDOM ve SAX'in aksine ElementTree'yi kullanarak XML dosyasının öğelerini ve değerlerini kolayca değiştirebilir ve güncelleyebilirsiniz. Bir sonraki bölümde nasıl olduğunu kontrol edelim.

ElementTree ile XML dosyaları nasıl değiştirilir?

Diyelim ki Noel tatili zamanı geldi ve acente paket maliyetlerini ikiye katlamak istiyor. ElementTree sağlar Ayarlamak() için kullanabileceğimiz fonksiyon güncelleştirme elemanların değerleri. Aşağıdaki kodda, her paketin fiyatına iter() işlevi aracılığıyla eriştim ve fiyatları manipüle ettim. Güncellenmiş öğelerle yeni bir XML dosyası yazmak için write() işlevini kullanabilirsiniz.

for price in root.iter('price'):
new_price = int(price.text)*2
price.text = str(new_price)
price.set('updated', 'yes')
tree.write('christmas_packages.xml')

Aşağıdaki görüntüdeki gibi bir çıktı dosyası bulabilmeniz gerekir. Hatırlarsanız Paris Vacation ve Hawaii Adventure fiyatları orijinal dosyada 3000$ ve 4000$'dır.

Python kullanarak XML dosyaları nasıl ayrıştırılır? PlatoBlockchain Veri Zekası. Dikey Arama. Ai.

Ancak, yeni bir etiket eklemek istersek ne olur? Sunulan konaklamanın 'Premium özel villa' olduğunu belirtmek için Andaman paketine. bu Alt Öğe() ElementTree'nin işlevi bize yeni alt etiketler ekle aşağıdaki kod parçacığında gösterildiği gibi ihtiyaca göre. Değiştirmek istediğiniz öğeyi ve yeni etiketi işleve parametre olarak iletmelisiniz.

ET.SubElement(root[3], 'stay')
for x in root.iter('stay'):
resort = 'Premium Private Villa'
x.text = str(resort)
Python kullanarak XML dosyaları nasıl ayrıştırılır? PlatoBlockchain Veri Zekası. Dikey Arama. Ai.

Umarım siz de sonuçları alırsınız! Paket ayrıca sağlar pop() Gereksiz olmaları durumunda nitelikleri ve alt öğeleri silebileceğiniz işlev.


XML (SAX) için basit API

SAX, belgeyi sırayla okuyarak miniDOM'un eksikliğini gideren başka bir python ayrıştırıcısıdır. Ağacın tamamını hafızasına yüklemez ve ayrıca hafıza kullanımını azaltarak öğeleri atmanıza izin verir.

İlk olarak, XML belgesinde işlemek istediğiniz farklı olaylar için bir SAX ayrıştırıcı nesnesi oluşturalım ve geri çağırma işlevlerini kaydedelim. Bunu yapmak için, SAX'in ContentHandler'ını alt sınıflandırarak aşağıda gösterildiği gibi özel bir TravelPackageHandler sınıfı tanımlıyorum.

import xml.sax
# Define a custom SAX ContentHandler class to handle events
class TravelPackageHandler(xml.sax.ContentHandler):
def __init__(self):
self.packages = []
self.current_package = {}
self.current_element = ""
self.current_payment = {} def startElement(self, name, attrs):
self.current_element = name
if name == "package":
self.current_package = {"id": attrs.getValue("id")} def characters(self, content):
if self.current_element in ["description", "destination", "price", "duration", "EMIoption", "refund"]:
self.current_package[self.current_element] = content.strip()
if self.current_element == "payment":
self.current_payment = {} def endElement(self, name):
if name == "package":
self.current_package["payment"] = self.current_payment
self.packages.append(self.current_package)
if name == "payment":
self.current_package["payment"] = self.current_payment def startElementNS(self, name, qname, attrs):
pass def endElementNS(self, name, qname):
pass

Yukarıdaki kesitte, startElement(), karakterler(), ve endElement() Yöntemler, verileri XML öğelerinden ve özniteliklerinden çıkarmak için kullanılır. SAX ayrıştırıcı belgeyi okurken, karşılaştığı her olay için kayıtlı geri arama işlevlerini tetikler. Örneğin, yeni bir öğenin başlangıcıyla karşılaşırsa, startElement() işlevini çağırır. Şimdi, örnek XML dosyamızı ayrıştıran çeşitli paket kimliklerini almak için özel işleyicimizi kullanalım.

# Create a SAX parser object
parser = xml.sax.make_parser()
handler = TravelPackageHandler()
parser.setContentHandler(handler)
parser.parse("travel_pckgs.xml")
for package in handler.packages:
print(f'Package: {package["id"]}')

çıktı >>

Paket: Paris tatili

Paket: Hawaii Macerası

Paket: İtalyan Kaçamağı

Paket: Andaman Island Retreat

SAX, verimliliği nedeniyle büyük dosyalar ve akış için kullanılabilir. Ancak, derinlemesine iç içe geçmiş öğelerle çalışırken sakıncalıdır. Herhangi bir rastgele ağaç düğümüne erişmek isterseniz ne olur? Rastgele erişimi desteklemediğinden, ayrıştırıcının belirli bir öğeye erişmek için tüm belgeyi sırayla okuması gerekir.


Tüm çift girişlerinizi Nanonets ile senkronize edin. Tüm hesaplarınızı 24×7 dengede tutun. Muhasebe süreçlerinizi <15 dakikada kurun. Bakın nasıl.


XML için Akış Çekme Ayrıştırıcısı

Bu pulldom DOM benzeri bir arayüze sahip bir akış çekme ayrıştırıcı API'si sağlayan Python kitaplığı.

Nasıl Çalışır?

XML verilerini “çekme” şeklinde işler. Yani, ayrıştırıcıdan XML verilerinde bir sonraki olayı (örneğin, başlangıç ​​öğesi, bitiş öğesi, metin vb.) sağlamasını açıkça talep edersiniz.

Sözdizimi, önceki kitaplıklarda gördüklerimize aşinadır. Aşağıdaki kodda, kütüphaneyi içe aktarmayı ve 4 gün veya daha uzun süreli turları yazdırmak için nasıl kullanılacağını ve ayrıca iptal durumunda geri ödeme sağlayacağını gösteriyorum.

from xml.dom.pulldom import parse
events = parse("travel_pckgs.xml")
for event, node in events:
if event == pulldom.START_ELEMENT and node.tagName == 'package':
duration = int(node.getElementsByTagName('duration')[0].firstChild.data)
refund = node.getElementsByTagName('refund')[0].firstChild.data.strip("'")
if duration > 4 and refund == 'yes':
print(f"Package: {node.getAttribute('id')}")
print(f"Duration: {duration}")
print(f"Refund: {refund}")

Şunun gibi bir çıktı almalısınız:

Paket: Paris tatili

Süre: 7

Geri ödeme: evet

Paket: Andaman Island Retreat

Süre: 8

Geri ödeme: evet

Sonuçları kontrol edin! Çekme çözümleyici, miniDOM ve SAX'in birkaç özelliğini birleştirerek nispeten verimli hale getirir.

Özet

Şimdiye kadar python'da bulunan çeşitli ayrıştırıcıları iyi bir şekilde kavradığınıza eminim. Zamandan ve kaynaklardan tasarruf etmek için hangi ayrıştırıcıyı ne zaman seçeceğinizi bilmek de eşit derecede önemlidir. Gördüğümüz tüm ayrıştırıcılar arasında ElementTree, karmaşık sorgular gerçekleştirmeye yardımcı olan XPath ifadeleriyle maksimum uyumluluk sağlar. Minidom, kullanımı kolay bir arayüze sahiptir ve küçük dosyalarla çalışmak için seçilebilir, ancak büyük dosyalar söz konusu olduğunda çok yavaştır. Aynı zamanda, gerçek zamanlı Makine öğreniminde olduğu gibi, XML dosyasının sürekli güncellendiği durumlarda SAX kullanılır.

Dosyalarınızı ayrıştırmanın bir alternatifi, Nanonets gibi otomatik ayrıştırma araçlarını kullanmaktır. Nanonet'ler, tek bir satır kod yazmadan her türlü belgeden saniyeler içinde veri çıkarmanıza yardımcı olabilir.

Oiş performansınızı optimize edin, maliyetlerden tasarruf edin ve büyümeyi artırın. Bulmak Nanonetlerin kullanım durumlarının ürününüze nasıl uygulanabileceği.


Zaman Damgası:

Den fazla AI ve Makine Öğrenimi