چگونه فایل های XML را با استفاده از پایتون تجزیه کنیم؟

چگونه فایل های XML را با استفاده از پایتون تجزیه کنیم؟

از سفارش مواد غذایی از طریق Instamart و خرید کمد لباس در Myntra گرفته تا رزرو تعطیلات در MakemyTrip، وب سایت ها در این دهه ضروری شده اند! آیا تا به حال فکر کرده اید که چگونه این وب سایت ها اطلاعات را برای مشتریان به روشی قابل تفسیر به راحتی نمایش می دهند و همچنین داده های موجود در backend را پردازش و با آنها تعامل می کنند؟

فرمت‌های فایل خاصی وجود دارند که این شکاف را پر می‌کنند و هم برای زبان ماشین و هم برای انسان قابل تفسیر هستند. یکی از این فرمت‌های پرکاربرد XML است که مخفف Extensible Markup Language است.

فایل های XML چیست و چگونه از آنها استفاده کنیم؟

فایل های XML برای ذخیره و انتقال داده ها بین کلاینت ها و سرورها استفاده می شوند. این به ما اجازه می دهد تا داده ها را در قالبی ساختاریافته از طریق برچسب ها، ویژگی ها و مقادیر تعریف کنیم. یکی از مزایای اصلی XML انعطاف پذیری آن است. می توان از آن برای نمایش داده ها در فرمت های مختلف استفاده کرد و به راحتی با استفاده های جدید سازگار شد. این باعث می‌شود که آن را برای برنامه‌هایی مانند وب سرویس‌ها، تبادل داده و فایل‌های پیکربندی انتخابی محبوب کنید. در این مقاله، شما را با روش‌های مختلف در پایتون برای تجزیه یک فایل XML با یک مثال عملی آشنا می‌کنم.


آیا به دنبال تجزیه خودکار XML هستید؟ گردش کار خودکار Nanonets را امتحان کنید. آزمایش رایگان خود را اکنون شروع کنید.


آشنایی با ساختار فایل های XML

قبل از اینکه به جزئیات نحوه تجزیه فایل‌های XML بپردازیم، ابتدا بخش‌های مختلف یک سند XML را درک می‌کنیم. در XML، یک عنصر یک بلوک ساختمانی اساسی از یک سند است که یک قطعه ساختار یافته از اطلاعات را نشان می دهد. محتوای عنصر باید بین یک تگ باز و یک تگ بسته همیشه مطابق شکل زیر محصور شود.

هری پاتر و سنگ جادو

من از یک فایل مثال استفاده خواهم کرد، "travel_pckgs.xml" که حاوی جزئیات بسته های مختلف تور ارائه شده توسط یک شرکت است. من به استفاده از همان فایل در سراسر وبلاگ برای وضوح ادامه خواهم داد.

<?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>

این فایل دارای داده های 4 بسته تور است که جزئیات مقصد، توضیحات، قیمت و گزینه های پرداخت ارائه شده توسط آژانس ارائه شده است. بیایید به تفکیک بخش های مختلف XML بالا نگاه کنیم:

  • عنصر ریشه: بالاترین سطح عنصر به عنوان ریشه نامیده می شود در پرونده ما این شامل تمام عناصر دیگر است (تورهای مختلف ارائه شده)
  • صفت: «id» ویژگی هر کدام است عنصر در فایل ما توجه داشته باشید که مشخصه باید مقادیر منحصر به فردی ("تعطیلات پاریس"، "ماجراجویی هاوایی" و غیره) برای هر عنصر داشته باشد. همانطور که می بینید معمولاً مشخصه و مقدار آن در داخل تگ شروع ذکر می شود.
  • عناصر کودک: عناصر پیچیده شده در داخل ریشه عناصر فرزند هستند. در مورد ما، همه   برچسب‌ها عناصر کودک هستند که هر کدام جزئیات مربوط به یک بسته تور را ذخیره می‌کنند.
  • عناصر فرعی: یک عنصر فرزند می تواند عناصر فرعی بیشتری در ساختار خود داشته باشد. را عنصر فرزند دارای عناصر فرعی است ، ، ، و . مزیت XML این است که به شما امکان می دهد اطلاعات سلسله مراتبی را از طریق چندین عنصر تو در تو ذخیره کنید. را عنصر فرعی نیز دارای عناصر فرعی است و، که نشان می دهد آیا یک بسته خاص گزینه های «پرداخت از طریق EMI» و بازپرداخت را دارد یا خیر.

نکته: می‌توانید یک نمای درختی از فایل XML ایجاد کنید تا با استفاده از آن به درک واضحی دست یابید ابزار. نمای درختی سلسله مراتبی فایل XML ما را بررسی کنید!

چگونه فایل های XML را با استفاده از پایتون تجزیه کنیم؟ هوش داده PlatoBlockchain. جستجوی عمودی Ai.

عالی! ما می خواهیم داده های ذخیره شده در این فیلدها را بخوانیم، جستجو کنیم، به روز رسانی کنیم و تغییرات لازم را برای وب سایت ایجاد کنیم، درست است؟ به این کار تجزیه می گویند، که در آن داده های XML به قطعات تقسیم می شوند و قسمت های مختلف شناسایی می شوند.

راه های مختلفی برای تجزیه یک فایل XML در پایتون با کتابخانه های مختلف وجود دارد. بیایید به روش اول شیرجه بزنیم!


Nanonets را برای تجزیه فایل های XML امتحان کنید. آزمایشی رایگان خود را بدون هیچ گونه جزئیات کارت اعتباری شروع کنید.


استفاده از Mini DOM برای تجزیه فایل های XML

من مطمئن هستم که با DOM (مدل شیء سند)، یک API استاندارد برای نمایش فایل‌های XML مواجه شده‌اید. Mini DOM یک ماژول داخلی پایتون است که DOM را به حداقل می رساند.  

mini DOM چگونه کار می کند؟

فایل XML ورودی را در حافظه بارگذاری می‌کند و یک ساختار درخت مانند "DOM Tree" برای ذخیره عناصر، ویژگی‌ها و محتوای متنی ایجاد می‌کند. از آنجایی که فایل‌های XML به طور ذاتی دارای ساختار درختی سلسله مراتبی هستند، این روش برای پیمایش و بازیابی اطلاعات راحت است.

بیایید ببینیم که چگونه بسته را با کد زیر وارد کنیم. می توانید فایل XML را با استفاده از آن تجزیه کنید xml.dom.minidom.parse() تابع و همچنین عنصر ریشه را دریافت کنید.

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)

خروجی ای که برای کد بالا گرفتم اینه:

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

فرض کنید می‌خواهم مکان، مدت و قیمت هر بسته را چاپ کنم.  

La getAttribute() تابع می تواند برای بازیابی مقدار یک ویژگی یک عنصر استفاده شود.

اگر می خواهید به تمام عناصر زیر یک برچسب خاص دسترسی داشته باشید، از getElementsByTagName()  روش و تگ را به عنوان ورودی ارائه کنید. بهترین بخش این است که getElementsByTagName() را می توان به صورت بازگشتی برای استخراج عناصر تو در تو استفاده کرد.

# 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)

خروجی کد بالا در اینجا نشان داده شده است که شناسه، متن توضیحات و مقادیر قیمت هر بسته استخراج و چاپ شده است.

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 همچنین به ما اجازه می دهد تا درخت DOM را از یک عنصر به عنصر والد، عنصر فرزند اول، آخرین فرزند و غیره پیمایش کنیم. شما می توانید به فرزند اول دسترسی داشته باشید عنصر با استفاده از بچه اول صفت. نام گره و مقدار عنصر فرزند استخراج شده نیز می تواند از طریق چاپ شود nodeName و nodeValue ویژگی هایی که در زیر نشان داده شده است.

# 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

می‌توانید تأیید کنید که «توضیح» اولین عنصر فرزند است . همچنین یک ویژگی به نام وجود دارد childNodes که تمام عناصر فرزند موجود در گره فعلی را برمی گرداند. مثال زیر و خروجی آن را بررسی کنید.

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>]

مشابه این، minidom راه‌های بیشتری را برای پیمایش مانند parentNode، lastChild nextSibling و غیره ارائه می‌کند. می‌توانید تمام عملکردهای موجود کتابخانه را بررسی کنید. اینجا کلیک نمایید.

اما، یک اشکال عمده این روش استفاده گران از حافظه است زیرا کل فایل در حافظه بارگذاری می شود. استفاده از minidom برای فایل های بزرگ غیر عملی است. 


نانوشبکه‌های تجزیه XML را خودکار کنید. دوره آزمایشی رایگان خود را امروز شروع کنید. کارت اعتباری مورد نیاز نیست.


استفاده از کتابخانه ElementTree برای تجزیه فایل های XML

ElementTree یک تجزیه کننده داخلی پایتون است که توابع زیادی برای خواندن، دستکاری و اصلاح فایل های XML ارائه می دهد. این تجزیه کننده یک ساختار درخت مانند ایجاد می کند تا داده ها را در قالب سلسله مراتبی ذخیره کند.

بیایید با وارد کردن کتابخانه و فراخوانی تابع parse() فایل XML خود شروع کنیم. همچنین می توانید فایل ورودی را به صورت رشته ای تهیه کنید و از آن استفاده کنید fromstring() تابع. پس از اینکه یک درخت تجزیه شده را مقداردهی اولیه کردیم، می توانیم استفاده کنیم ریشه گرفتن () تابع برای بازیابی تگ ریشه مطابق شکل زیر است.

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' استخراج شد!

بیایید بگوییم که اکنون می خواهیم دسترسی همه برچسب های فرزند اول از ریشه می‌توانیم از یک حلقه برای ساده استفاده کنیم و روی آن تکرار کنیم، تگ‌های فرزند مانند مقصد، قیمت و غیره را چاپ کنیم... توجه داشته باشید که اگر مقدار مشخصه‌ای را در تگ ابتدایی توضیحات مشخص کرده بودیم، پرانتز خالی نبود. قطعه زیر را بررسی کنید!

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

از طرف دیگر ، iter() تابع می تواند به شما کمک کند هر عنصر مورد علاقه را در کل درخت پیدا کنید. بیایید از این برای استخراج توضیحات هر بسته تور در فایل خود استفاده کنیم. به یاد داشته باشید که از "متن" ویژگی برای استخراج متن یک عنصر.

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، حلقه for اولیه برای دسترسی به عناصر فرزند بسیار قدرتمند است. بیایید ببینیم چگونه.

تجزیه فایل های XML با حلقه for

شما به سادگی می توانید از طریق عناصر فرزند با یک حلقه for تکرار کنید و ویژگی ها را مطابق شکل زیر استخراج کنید.

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

برای رسیدگی به پرس و جو و فیلترینگ پیچیده، ElementTee دارای این است findall() روش. این روش به شما امکان می دهد به تمام عناصر فرزند تگ ارسال شده به عنوان پارامتر دسترسی داشته باشید. فرض کنید می‌خواهید بسته‌های تور زیر 4000 دلار را بشناسید و همچنین دارای گزینه EMI به عنوان "بله" هستند. قطعه را بررسی کنید.

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'])

ما اساساً روی بسته ها از طریق root.findall ('package') تکرار می کنیم و سپس قیمت را استخراج می کنیم و با استفاده از آن بازپرداخت می کنیم. پیدا کردن() روش. پس از این، ما محدودیت ها را بررسی می کنیم و بسته های واجد شرایط را که در زیر چاپ شده اند فیلتر می کنیم.

خروجی:

>>

تعطیلات پاریس

عقب نشینی جزیره آندامان

با استفاده از ElementTree، بر خلاف miniDOM و SAX می توانید به راحتی عناصر و مقادیر فایل XML را تغییر داده و به روز کنید. بیایید بررسی کنیم که چگونه در بخش بعدی.

چگونه فایل های XML را با ElementTree تغییر دهیم؟

فرض کنید زمان تعطیلات کریسمس است و آژانس می خواهد هزینه های بسته را دو برابر کند. ElementTree ارائه می دهد تنظیم() تابعی که می توانیم از آن استفاده کنیم به روز رسانی ارزش عناصر در کد زیر، من از طریق تابع iter() به قیمت هر بسته دسترسی پیدا کرده ام و قیمت ها را دستکاری کرده ام. می توانید از تابع write() برای نوشتن یک فایل XML جدید با عناصر به روز شده استفاده کنید.

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')

شما باید بتوانید یک فایل خروجی مانند تصویر زیر پیدا کنید. اگر به خاطر داشته باشید، قیمت تعطیلات پاریس و ماجراجویی هاوایی در فایل اصلی 3000 دلار و 4000 دلار است.

چگونه فایل های XML را با استفاده از پایتون تجزیه کنیم؟ هوش داده PlatoBlockchain. جستجوی عمودی Ai.

اما اگر بخواهیم یک تگ جدید اضافه کنیم چه می شود به بسته Andaman نشان می دهد که اقامت ارائه شده "ویلای خصوصی ممتاز" است. را SubElement() تابع ElementTree به ما اجازه می دهد برچسب های فرعی جدید اضافه کنید طبق نیاز، همانطور که در قطعه زیر نشان داده شده است. شما باید عنصری را که می خواهید تغییر دهید و تگ جدید را به عنوان پارامتر به تابع منتقل کنید.

ET.SubElement(root[3], 'stay')
for x in root.iter('stay'):
resort = 'Premium Private Villa'
x.text = str(resort)
چگونه فایل های XML را با استفاده از پایتون تجزیه کنیم؟ هوش داده PlatoBlockchain. جستجوی عمودی Ai.

امیدوارم شما هم به نتیجه رسیده باشید! بسته نیز فراهم می کند ترکیدن() تابع، که از طریق آن می توانید ویژگی ها و عناصر فرعی را در صورت غیر ضروری حذف کنید.


API ساده برای XML (SAX)

SAX یکی دیگر از تجزیه کننده های پایتون است که با خواندن پی در پی سند، نقص miniDOM را برطرف می کند. کل درخت را در حافظه خود بارگذاری نمی کند و همچنین به شما امکان می دهد موارد را دور بیندازید و مصرف حافظه را کاهش دهید.

ابتدا، اجازه دهید یک شی تجزیه کننده SAX ایجاد کنیم و توابع برگشت تماس را برای رویدادهای مختلفی که می خواهید در سند XML مدیریت کنید، ثبت کنیم. برای انجام این کار، من یک کلاس TravelPackageHandler سفارشی را همانطور که در زیر نشان داده شده است، توسط زیر کلاس ContentHandler SAX تعریف می کنم.

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

در قطعه بالا، startElement()، کاراکترها()، و endElement() روش‌هایی برای استخراج داده‌ها از عناصر و ویژگی‌های XML استفاده می‌شوند. همانطور که تجزیه کننده SAX سند را می خواند، توابع بازگشت تماس ثبت شده را برای هر رویدادی که با آن مواجه می شود فعال می کند. برای مثال، اگر با شروع یک عنصر جدید مواجه شود، تابع startElement() را فراخوانی می کند. اکنون، بیایید از کنترلر سفارشی خود برای دریافت شناسه های بسته مختلف که فایل XML مثال خود را تجزیه می کنند، استفاده کنیم.

# 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"]}')

خروجی >>

بسته: تعطیلات پاریس

بسته: ماجراجویی هاوایی

پکیج: گریز ایتالیایی

بسته: خلوت جزیره آندامان

SAX به دلیل کارایی که دارد برای فایل های حجیم و استریم قابل استفاده است. اما هنگام کار با عناصر عمیق تو در تو ناخوشایند است. اگر بخواهید به هر گره درختی تصادفی دسترسی داشته باشید چه؟ از آنجایی که از دسترسی تصادفی پشتیبانی نمی کند، تجزیه کننده باید تمام سند را به صورت متوالی بخواند تا به یک عنصر خاص دسترسی پیدا کند.


همه ورودی های دوگانه خود را با نانو شبکه ها همگام سازی کنید. تمام حساب های خود را متعادل نگه دارید، 24×7. فرآیندهای حسابداری خود را در کمتر از 15 دقیقه تنظیم کنید. ببینید که چگونه.


پخش جریانی Pull Parser برای XML

این است pulldom کتابخانه پایتون که یک API تجزیه‌کننده جریانی با رابط DOM مانند ارائه می‌کند.

چگونه کار می کند؟

داده های XML را به شیوه ای "کشش" پردازش می کند. یعنی شما صریحاً از تجزیه کننده درخواست می کنید که رویداد بعدی (به عنوان مثال، عنصر شروع، عنصر پایان، متن و غیره) را در داده های XML ارائه دهد.

نحو با آنچه در کتابخانه های قبلی دیده ایم آشناست. در کد زیر، نحوه وارد کردن کتابخانه و استفاده از آن برای چاپ تورهایی که 4 روز یا بیشتر هستند را نشان می‌دهم و همچنین در صورت لغو، بازپرداخت می‌دهم.

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}")

شما باید خروجی هایی مانند:

بسته: تعطیلات پاریس

مدت زمان: 7

بازپرداخت: بله

بسته: خلوت جزیره آندامان

مدت زمان: 8

بازپرداخت: بله

نتایج را بررسی کنید! تجزیه کننده کششی چند ویژگی از miniDOM و SAX را ترکیب می کند و آن را نسبتاً کارآمد می کند.

خلاصه

من مطمئن هستم که تا به حال درک خوبی از تجزیه کننده های مختلف موجود در پایتون دارید. دانستن زمان انتخاب تجزیه کننده برای صرفه جویی در زمان و منابع به همان اندازه مهم است. در میان تمام تجزیه کننده هایی که دیدیم، ElementTree حداکثر سازگاری را با عبارات XPath فراهم می کند که به انجام پرس و جوهای پیچیده کمک می کند. Minidom رابط کاربری آسانی دارد و می تواند برای رسیدگی به فایل های کوچک انتخاب شود، اما در مورد فایل های بزرگ بسیار کند است. در عین حال، SAX در شرایطی استفاده می‌شود که فایل XML دائماً به‌روزرسانی می‌شود، مانند مورد یادگیری ماشینی بلادرنگ.

یکی از جایگزین‌های تجزیه فایل‌های شما، استفاده از ابزارهای تجزیه خودکار مانند Nanonets است. نانوشبکه‌ها می‌توانند به شما در استخراج داده‌ها از هر نوع سندی در عرض چند ثانیه بدون نوشتن یک خط کد کمک کنند.

Oعملکرد کسب و کار خود را بهینه کنید، در هزینه ها صرفه جویی کنید و رشد را افزایش دهید. پیدا کردن چگونه موارد استفاده نانوشبکه ها می تواند برای محصول شما اعمال شود.


تمبر زمان:

بیشتر از هوش مصنوعی و یادگیری ماشین