وبلاگ رسانگار
با ما حرفه ای باشید

سرور مجازی NVMe

خواندن و نوشتن فایل های XML در پایتون

0 92
زمان لازم برای مطالعه: 9 دقیقه


XML یا زبان نشانه گذاری توسعه پذیر یک زبان نشانه گذاری است که معمولاً برای ساختار، ذخیره و انتقال داده ها بین سیستم ها استفاده می شود. اگرچه مانند گذشته رایج نیست، اما همچنان در خدماتی مانند RSS و SOAP و همچنین برای ساختاربندی فایل‌هایی مانند اسناد مایکروسافت آفیس استفاده می‌شود.

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

در طول این مقاله ما در درجه اول نگاهی به این خواهیم داشت ElementTree ماژول برای خواندن، نوشتن، و اصلاح داده های XML. ما همچنین آن را با قدیمی تر مقایسه خواهیم کرد minidom ماژول در چند بخش اول تا بتوانید مقایسه خوبی از این دو داشته باشید.

ماژول های XML

را minidomیا Minimal DOM Implementation، یک پیاده سازی ساده از Document Object Model (DOM) است. را DOM یک رابط برنامه نویسی کاربردی است که XML را به عنوان یک ساختار درختی در نظر می گیرد که در آن هر کدام node در درخت یک شی است. بنابراین، استفاده از این ماژول مستلزم آشنایی با عملکرد آن است.

را ElementTree ماژول یک رابط “پایتونیک” بیشتر برای مدیریت XMl فراهم می کند و گزینه خوبی برای کسانی است که با DOM آشنایی ندارند. همچنین به دلیل رابط کاربری ساده اش که در سراسر این مقاله خواهید دید، احتمالاً کاندیدای بهتری برای استفاده توسط برنامه نویسان تازه کار بیشتر است.

در این مقاله، ElementTree ماژول در همه مثال ها استفاده خواهد شد، در حالی که minidom همچنین نشان داده خواهد شد، اما فقط برای شمارش و خواندن اسناد XML.

نمونه فایل XML

در مثال‌های زیر، از فایل XML زیر استفاده می‌کنیم که آن را به‌عنوان «items.xml» ذخیره می‌کنیم:

<data>
    <items>
        <item name="item1">item1abc</item>
        <item name="item2">item2abc</item>
    </items>
</data>

همانطور که می بینید، این یک مثال نسبتا ساده XML است که فقط شامل چند شیء تو در تو و یک ویژگی است. با این حال، نشان دادن تمام عملیات XML در این مقاله باید کافی باشد.

خواندن اسناد XML

استفاده از minidom

به منظور تجزیه یک سند XML با استفاده از minidom، ابتدا باید import آن را از xml.dom مدول. این ماژول از parse تابع ایجاد یک شی DOM از فایل XML ما است. را parse تابع دارای نحو زیر است:

xml.dom.minidom.parse(filename_or_file(, parser(, bufsize)))

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

از آنجایی که هر کدام node را می توان به عنوان یک شی در نظر گرفت، ما می توانیم با استفاده از ویژگی های شی به ویژگی ها و متن یک عنصر دسترسی پیدا کنیم. در مثال زیر به ویژگی ها و متن یک خاص دسترسی پیدا کرده ایم node، و از همه گره ها با هم.

from xml.dom import minidom


mydoc = minidom.parse('items.xml')

items = mydoc.getElementsByTagName('item')


print('Item #2 attribute:')
print(items(1).attributes('name').value)


print('\nAll attributes:')
for elem in items:
    print(elem.attributes('name').value)


print('\nItem #2 data:')
print(items(1).firstChild.data)
print(items(1).childNodes(0).data)


print('\nAll item data:')
for elem in items:
    print(elem.firstChild.data)

نتیجه به شرح زیر است:

$ python minidomparser.py 
Item 
item2

All attributes:
item1
item2

Item 
item2abc
item2abc

All item data:
item1abc
item2abc

شکل 1

اگر می‌خواهیم از فایلی که قبلاً باز شده است استفاده کنیم، فقط می‌توانیم شی فایل خود را به آن منتقل کنیم parse مانند:

datasource = open('items.xml')


mydoc = parse(datasource)

همچنین، اگر داده‌های XML قبلاً به‌عنوان یک رشته بارگذاری شده بودند، می‌توانستیم از آن استفاده کنیم parseString() در عوض عملکرد

با استفاده از ElementTree

ElementTree راه بسیار ساده ای را به ما ارائه می دهد process فایل های XML مثل همیشه، برای استفاده از آن ابتدا باید import ماژول در کد ما از import فرمان با as کلمه کلیدی که به ما امکان می دهد از یک نام ساده شده استفاده کنیم (ET در این مورد) برای ماژول در کد.

دنبال کردن import، یک ساختار درختی با parse تابع، و ما آن را بدست می آوریم root عنصر زمانی که ما به root node ما به راحتی می توانیم از اطراف درخت عبور کنیم، زیرا یک درخت یک نمودار متصل است.

استفاده کردن ElementTreeو مانند مثال کد قبلی، کد را بدست می آوریم node ویژگی ها و متن با استفاده از اشیاء مربوط به هر یک node.

کد به شرح زیر است:

import xml.etree.ElementTree as ET
tree = ET.parse('items.xml')
root = tree.getroot()


print('Item #2 attribute:')
print(root(0)(1).attrib)


print('\nAll attributes:')
for elem in root:
    for subelem in elem:
        print(subelem.attrib)


print('\nItem #2 data:')
print(root(0)(1).text)


print('\nAll item data:')
for elem in root:
    for subelem in elem:
        print(subelem.text)

نتیجه به شرح زیر خواهد بود:

$ python treeparser.py 
Item 
item2

All attributes:
item1
item2

Item 
item2abc

All item data:
item1abc
item2abc

شکل 2

همانطور که می بینید، این بسیار شبیه به minidom مثال. یکی از تفاوت های اصلی این است که attrib شی به سادگی یک شی دیکشنری است که باعث می شود تا کمی با سایر کدهای پایتون سازگاری داشته باشد. ما همچنین نیازی به استفاده نداریم value برای دسترسی به مقدار ویژگی آیتم مانند قبل.

ممکن است متوجه شده باشید که چگونه به اشیا و ویژگی ها دسترسی پیدا می کنید ElementTree همانطور که قبلا ذکر کردیم کمی پایتونیک تر است. این به این دلیل است که داده‌های XML برخلاف با به‌صورت فهرست‌ها و فرهنگ‌های ساده تجزیه می‌شوند minidom جایی که موارد به صورت سفارشی تجزیه می شوند xml.dom.minidom.Attr و “گره های متن DOM”.

شمارش عناصر یک سند XML

استفاده از minidom

همانطور که در مورد قبلی، minidom باید از کشور وارد شود dom مدول. این ماژول عملکرد را ارائه می دهد getElementsByTagName، که از آن برای یافتن مورد برچسب استفاده می کنیم. پس از به دست آوردن، ما از آن استفاده می کنیم len() روش داخلی برای به دست آوردن تعداد موارد فرعی متصل به a node. نتیجه به دست آمده از کد زیر نشان داده شده است شکل 3.

from xml.dom import minidom


mydoc = minidom.parse('items.xml')

items = mydoc.getElementsByTagName('item')


print(len(items))
$ python counterxmldom.py
2

شکل 3

به خاطر داشته باشید که این خواهد شد فقط تعداد آیتم های فرزند را در زیر یادداشتی که اجرا می کنید بشمارید len() روی، که در این مورد است root node. اگر می خواهید همه عناصر فرعی را در یک درخت بسیار بزرگتر بیابید، باید از همه عناصر عبور کنید و هر یک از فرزندان آنها را بشمارید.

با استفاده از ElementTree

به طور مشابه، ElementTree ماژول به ما اجازه می دهد تا مقدار گره های متصل به a را محاسبه کنیم node.

کد مثال:

import xml.etree.ElementTree as ET
tree = ET.parse('items.xml')
root = tree.getroot()


print(len(root(0)))

نتیجه به شرح زیر است:

$ python counterxml.py
2

شکل 4

نوشتن اسناد XML

با استفاده از ElementTree

ElementTree همچنین برای نوشتن داده ها بر روی فایل های XML عالی است. کد زیر روش ایجاد یک فایل XML با ساختار مشابه فایلی که در مثال های قبلی استفاده کردیم را نشان می دهد.

مراحل عبارتند از:

  1. یک عنصر ایجاد کنید که مانند ما عمل کند root عنصر در مورد ما تگ این عنصر “داده” است.
  2. زمانی که ما خودمان را داریم root عنصر، ما می توانیم عناصر فرعی را با استفاده از SubElement تابع. این تابع دارای نحو است:

SubElement(parent, tag, attrib={}, **extra)

اینجا parent پدر و مادر است node برای اتصال به attrib یک فرهنگ لغت حاوی ویژگی های عنصر و extra آرگومان های کلمه کلیدی اضافی هستند. این تابع یک عنصر را به ما برمی‌گرداند که می‌توان از آن برای پیوست کردن سایر عناصر فرعی استفاده کرد، همانطور که در خطوط زیر با ارسال موارد به SubElement سازنده
3. اگرچه می توانیم ویژگی های خود را با the اضافه کنیم SubElement تابع، ما همچنین می توانیم از set() عملکرد، همانطور که در کد زیر انجام می دهیم. متن عنصر با ایجاد می شود text دارایی از Element هدف – شی.
4. در 3 خط آخر کد زیر یک رشته از درخت XML ایجاد می کنیم و آن داده ها را در فایلی که باز می کنیم می نویسیم.

کد مثال:

import xml.etree.ElementTree as ET


data = ET.Element('data')
items = ET.SubElement(data, 'items')
item1 = ET.SubElement(items, 'item')
item2 = ET.SubElement(items, 'item')
item1.set('name','item1')
item2.set('name','item2')
item1.text = 'item1abc'
item2.text = 'item2abc'


mydata = ET.tostring(data)
myfile = open("items2.xml", "w")
myfile.write(mydata)

اجرای این کد منجر به یک فایل جدید به نام “items2.xml” می شود که حداقل از نظر ساختار داده XML باید معادل فایل اصلی “items.xml” باشد. احتمالاً متوجه خواهید شد که رشته حاصل فقط یک خط است و هیچ تورفتگی ندارد.

یافتن عناصر XML

با استفاده از ElementTree

را ElementTree ماژول ارائه می دهد findall() تابع، که به ما در یافتن موارد خاص در درخت کمک می کند. همه موارد را با شرایط مشخص شده برمی گرداند. علاوه بر این، ماژول دارای عملکرد است find()، که فقط برمی گرداند اولین عنصر فرعی که با معیارهای مشخص شده مطابقت دارد. سینتکس هر دوی این توابع به شرح زیر است:

findall(match, namespaces=None)
find(match, namespaces=None)

برای هر دوی این توابع match پارامتر می تواند یک نام تگ XML یا یک مسیر باشد. کارکرد findall() لیستی از عناصر و را برمی گرداند find یک شی از نوع واحد را برمی گرداند Element.

علاوه بر این، یک تابع کمکی دیگر وجود دارد که متن اولین را برمی گرداند node که با معیار داده شده مطابقت دارد:

findtext(match, default=None, namespaces=None)

در اینجا چند نمونه کد برای نشان دادن روش عملکرد این توابع وجود دارد:

import xml.etree.ElementTree as ET
tree = ET.parse('items.xml')
root = tree.getroot()


for elem in root:
    print(elem.find('item').get('name'))


for elem in root:
    for subelem in elem.findall('item'):
    
        
        print(subelem.attrib)      
    
        
        print(subelem.get('name'))

و این هم نتیجه اجرای مجدد این کد:

$ python findtree.py 
item1
{'name': 'item1'}
item1
{'name': 'item2'}
item2

شکل 5

اصلاح عناصر XML

با استفاده از ElementTree

را ElementTree ماژول چندین ابزار برای اصلاح اسناد XML موجود ارائه می دهد. مثال زیر روش تغییر نام a را نشان می دهد node، نام یک ویژگی را تغییر دهید و مقدار آن را تغییر دهید و چگونه یک ویژگی اضافی به یک عنصر اضافه کنید.

آ node متن را می توان با تعیین مقدار جدید در قسمت متن تغییر داد node هدف – شی. نام مشخصه را می توان با استفاده از عبارت دوباره تعریف کرد set(name, value) تابع. را set تابع نباید فقط کار کند روی یک ویژگی موجود، همچنین می تواند برای تعریف یک ویژگی جدید استفاده شود.

کد زیر روش انجام این عملیات را نشان می دهد:

import xml.etree.ElementTree as ET

tree = ET.parse('items.xml')
root = tree.getroot()


for elem in root.iter('item'):
    elem.text = 'new text'


for elem in root.iter('item'):
    elem.set('name', 'newitem')


for elem in root.iter('item'):
    elem.set('name2', 'newitem2')

tree.write('newitems.xml')

پس از اجرای کد، فایل XML ایجاد شده “newitems.xml” دارای یک درخت XML با داده های زیر خواهد بود:

<data>
    <items>
        <item name="newitem" name2="newitem2">new text</item>
        <item name="newitem" name2="newitem2">new text</item>
    </items>
</data>

همانطور که می بینیم هنگام مقایسه با فایل XML اصلی، نام عناصر آیتم به “newitem”، متن به “new text” و ویژگی “name2” به هر دو گره اضافه شده است.

همچنین ممکن است متوجه شوید که نوشتن داده های XML به این روش (تماس tree.write با نام فایل) قالب بندی بیشتری به درخت XML اضافه می کند تا حاوی خطوط جدید و تورفتگی باشد.

ایجاد عناصر فرعی XML

با استفاده از ElementTree

را ElementTree ماژول بیش از یک راه برای افزودن یک عنصر جدید دارد. اولین راهی که به آن نگاه خواهیم کرد استفاده از makeelement() تابع، که دارای node نام و فرهنگ لغت با ویژگی های آن به عنوان پارامتر.

راه دوم از طریق SubElement() کلاس، که عنصر والد و فرهنگ لغت ویژگی ها را به عنوان ورودی می گیرد.

در مثال زیر هر دو روش را نشان می دهیم. در مورد اول node هیچ ویژگی ندارد، بنابراین ما یک فرهنگ لغت خالی ایجاد کردیم (attrib = {}). در حالت دوم، از دیکشنری پر شده برای ایجاد ویژگی ها استفاده می کنیم.

import xml.etree.ElementTree as ET

tree = ET.parse('items.xml')
root = tree.getroot()


attrib = {}
element = root.makeelement('seconditems', attrib)
root.append(element)


attrib = {'name2': 'secondname2'}
subelement = root(0)(1).makeelement('seconditem', attrib)
ET.SubElement(root(1), 'seconditem', attrib)
root(1)(0).text = 'seconditemabc'


tree.write('newitems2.xml')

پس از اجرای این کد، فایل XML حاصل به شکل زیر خواهد بود:

<data>
    <items>
        <item name="item1">item1abc</item>
        <item name="item2">item2abc</item>
    </items>
    <seconditems>
         <seconditem name2="secondname2">seconditemabc</seconditem>
    </seconditems>
</data>

همانطور که می بینیم هنگام مقایسه با فایل اصلی، عنصر “seconditems” و عنصر فرعی آن “seconditem” اضافه شده است. علاوه بر این، “مورد دوم” node دارای “name2” به عنوان یک ویژگی، و متن آن “seconditemabc” است، همانطور که انتظار می رود.

حذف عناصر XML

با استفاده از ElementTree

همانطور که احتمالاً انتظار دارید، ElementTree ماژول قابلیت های لازم برای حذف را دارد nodeویژگی ها و عناصر فرعی.

حذف یک ویژگی

کد زیر روش حذف a را نشان می دهد node’s ویژگی با استفاده از pop() تابع. تابع در مورد اعمال می شود attrib پارامتر شی نام ویژگی را مشخص می کند و آن را روی آن تنظیم می کند None.

import xml.etree.ElementTree as ET

tree = ET.parse('items.xml')
root = tree.getroot()


root(0)(0).attrib.pop('name', None)


tree.write('newitems3.xml')

نتیجه فایل XML زیر خواهد بود:

<data>
    <items>
        <item>item1abc</item>
        <item name="item2">item2abc</item>
    </items>
</data>

همانطور که در کد XML بالا می بینیم، اولین مورد هیچ ویژگی “name” ندارد.

حذف یک عنصر فرعی

یک عنصر فرعی خاص را می توان با استفاده از آن حذف کرد remove تابع. این تابع باید مشخص کند node که می خواهیم حذف کنیم.

مثال زیر روش استفاده از آن را به ما نشان می دهد:

import xml.etree.ElementTree as ET

tree = ET.parse('items.xml')
root = tree.getroot()


root(0).remove(root(0)(0))


tree.write('newitems4.xml')

نتیجه فایل XML زیر خواهد بود:

<data>
    <items>
        <item name="item2">item2abc</item>
    </items>
</data>

همانطور که از کد XML بالا می بینیم، اکنون فقط یک “آیتم” وجود دارد. node. مورد دوم از درخت اصلی حذف شده است.

حذف تمام عناصر فرعی

را ElementTree ماژول به ما ارائه می دهد clear() تابع، که می تواند برای حذف استفاده شود همه عناصر فرعی یک عنصر معین

مثال زیر روش استفاده را به ما نشان می دهد clear():

import xml.etree.ElementTree as ET

tree = ET.parse('items.xml')
root = tree.getroot()


root(0).clear()


tree.write('newitems5.xml')

نتیجه فایل XML زیر خواهد بود:

<data>
    <items />
</data>

همانطور که در کد XML بالا می بینیم، تمام عناصر فرعی عنصر “اقلام” از درخت حذف شده اند.

بسته بندی

پایتون چندین گزینه برای مدیریت فایل های XML ارائه می دهد. در این مقاله به بررسی آن پرداخته ایم ElementTree ماژول، و از آن برای تجزیه، ایجاد، اصلاح و حذف فایل های XML استفاده کرد. ما نیز استفاده کرده ایم minidom مدل برای تجزیه فایل های XML. من شخصاً استفاده از آن را توصیه می کنم ElementTree ماژول چون کار با آن بسیار ساده تر است و ماژول مدرن تری از این دو است.

(برچسب‌ها به ترجمه)# python



منتشر شده در 1403-01-28 23:22:05

امتیاز شما به این مطلب
دیدگاه شما در خصوص مطلب چیست ؟

آدرس ایمیل شما منتشر نخواهد شد.

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