כיצד לנתח קבצי XML באמצעות python?

כיצד לנתח קבצי XML באמצעות python?

מהזמנת מצרכים דרך אינסטמארט וקניות מלתחות ב-Myntra ועד הזמנת חופשות ב-MakemyTrip, אתרי אינטרנט הפכו חיוניים בעשור הזה! תהיתם פעם איך אתרים אלו מציגים מידע ללקוחות בצורה נוחה לפירוש וגם מעבדים ומקיימים אינטראקציה עם הנתונים ב-backend?

ישנם פורמטים מסוימים של קבצים המגשרים על הפער הזה, ניתנים לפירוש הן לשפת המכונה והן לבני אדם. פורמט אחד כזה בשימוש נרחב הוא XML, שהוא קיצור של Extensible Markup Language.

מהם קבצי XML וכיצד אנו משתמשים בהם?

קובצי XML משמשים לאחסון והעברה של נתונים בין לקוחות ושרתים. זה מאפשר לנו להגדיר את הנתונים בפורמט מובנה באמצעות תגים, תכונות וערכים. אחד היתרונות העיקריים של XML הוא הגמישות שלו. זה יכול לשמש לייצוג נתונים בפורמטים רבים ולהתאים בקלות לשימושים חדשים. זה הופך אותו לבחירה פופולרית עבור יישומים כגון שירותי אינטרנט, חילופי נתונים וקובצי תצורה. במאמר זה, אעביר אותך דרך השיטות השונות ב-python לניתוח קובץ XML עם דוגמה מעשית.


האם אתה מחפש ניתוח XML אוטומטי? נסה זרימות עבודה אוטומטיות של Nanonets. התחל את תקופת הניסיון בחינם שלך עכשיו.


הבנת המבנה של קבצי XML

לפני שנצלול לפרטים כיצד לנתח קובצי XML, בואו נבין תחילה את החלקים השונים של מסמך XML. ב-XML, an אלמנט הוא אבן בניין בסיסית של מסמך המייצג פיסת מידע מובנית. התוכן של האלמנט חייב להיות מוקף בין תג פתיחה ותג סוגר תמיד כפי שמוצג להלן.

הארי פוטר ואבן החכמים

אני אשתמש בקובץ לדוגמה, "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 לעיל:

  • אלמנט שורש: האלמנט ברמה העליונה מכונה השורש, כלומר בתיק שלנו. הוא מכיל את כל שאר האלמנטים (סיורים שונים מוצעים)
  • תְכוּנָה: 'מזהה' הוא התכונה של כל אחד מהם אלמנט בקובץ שלנו. שים לב שלתכונה חייבת להיות ערכים ייחודיים ('חופשה בפריז', 'הרפתקאות הוואי' וכו') עבור כל רכיב. התכונה והערך שלה מוזכרים בדרך כלל בתוך תג ההתחלה כפי שאתה יכול לראות.
  • אלמנטים של ילדים: האלמנטים העטופים בתוך השורש הם האלמנטים הבנים. במקרה שלנו, כל   תגים הם אלמנטים צאצאים, כל אחד מאחסן פרטים על חבילת סיור.
  • רכיבי משנה: לאלמנט צאצא יכולים להיות יותר תת-אלמנטים בתוך המבנה שלו. ה לאלמנט ילד יש תת-אלמנטים , , , ו . היתרון של XML הוא שהוא מאפשר לך לאחסן מידע היררכי באמצעות מספר אלמנטים מקוננים. ה תת-אלמנט יש עוד תת-אלמנטים ו, שמציינים אם לחבילה מסוימת יש אפשרויות 'תשלום דרך EMI' והחזר או לא.

טיפ: אתה יכול ליצור תצוגת עץ של קובץ ה-XML כדי לקבל הבנה ברורה באמצעות זה כלי. בדוק את תצוגת העץ ההיררכית של קובץ ה-XML שלנו!

כיצד לנתח קבצי XML באמצעות python? PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

גדול! אנחנו רוצים לקרוא את הנתונים המאוחסנים בשדות אלו, לחפש, לעדכן ולבצע שינויים לפי הצורך באתר, נכון? זה נקרא ניתוח, שבו נתוני ה-XML מפוצלים לחתיכות ומזהים חלקים שונים.

ישנן מספר דרכים לנתח קובץ XML ב-python עם ספריות שונות. בואו נצלול לשיטה הראשונה!


נסה את Nanonets לנתח קובצי XML. התחל את תקופת הניסיון בחינם ללא כל פרטי כרטיס אשראי.


שימוש ב-Mini DOM לניתוח קבצי XML

אני בטוח שהיית נתקל ב-DOM (Document Object Model), API סטנדרטי לייצוג קובצי XML. Mini DOM הוא מודול פיתון מובנה שמיישם DOM באופן מינימלי.  

איך מיני 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>

נניח שאני רוצה להדפיס את המקום, משך הזמן והמחיר של כל חבילה.  

השמיים 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 מאלמנט אחד לאלמנט האב שלו, אלמנט הבן הראשון שלו, הבן האחרון שלו וכו'. אתה יכול לגשת לילד הראשון של אלמנט באמצעות ה ילד ראשון תְכוּנָה. ניתן להדפיס גם את שם הצומת והערך של רכיב הצאצא שחולץ שם צומת ו צומת ערך תכונות כפי שמוצג להלן.

# 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

אתה יכול לוודא ש'description' הוא הרכיב הצאצא הראשון של . יש גם תכונה שנקראת צמתים שיחזיר את כל האלמנטים הבתים הנמצאים בתוך הצומת הנוכחי. בדוק את הדוגמה שלהלן ואת הפלט שלה.

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

בדומה לזה, מינידום מספק דרכים נוספות לחצות כמו parentNode, lastChild nextSibling וכו'. אתה יכול לבדוק את כל הפונקציות הזמינות של הספרייה כאן.

אבל, החיסרון העיקרי של שיטה זו הוא השימוש היקר בזיכרון מכיוון שהקובץ כולו נטען לזיכרון. זה לא מעשי להשתמש במינידום עבור קבצים גדולים. 


אוטומציה של ניתוח ננונטים של 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 {}

לחלופין, ה- איטר () הפונקציה יכולה לעזור לך למצוא כל אלמנט של עניין בעץ כולו. בואו נשתמש בזה כדי לחלץ את התיאורים של כל חבילת סיור בקובץ שלנו. זכור להשתמש ב- 'טֶקסט' תכונה כדי לחלץ את הטקסט של אלמנט.

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, ה-basic for loop הוא די חזק כדי לגשת לרכיבי הצאצא. בוא נראה איך.

ניתוח קובצי 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 יש את מצא הכל() שיטה. שיטה זו מאפשרת לך לגשת לכל רכיבי הצאצא של התג המועברים כפרמטרים. נניח שאתה רוצה לדעת את חבילות הטיולים שעולות מתחת ל-$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, ניתן לשנות ולעדכן בקלות את האלמנטים והערכים של קובץ ה-XML, בניגוד ל-miniDOM ו-SAX. בואו נבדוק איך בסעיף הבא.

כיצד לשנות קבצי 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 באמצעות python? PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

אבל, מה אם נרצה להוסיף תג חדש לחבילת אנדמן כדי לציין שהשהות המוצעת היא 'וילה פרטית פרימיום'. ה SubElement() הפונקציה של ElementTree מאפשרת לנו הוסף תגי משנה חדשים לפי הצורך, כפי שמוצג בקטע הבא. עליך להעביר את האלמנט שברצונך לשנות ואת התג החדש כפרמטרים לפונקציה.

ET.SubElement(root[3], 'stay')
for x in root.iter('stay'):
resort = 'Premium Private Villa'
x.text = str(resort)
כיצד לנתח קבצי XML באמצעות python? PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

מקווה שגם אתה קיבלת את התוצאות! החבילה מספקת גם פּוֹפּ() פונקציה, שבאמצעותה ניתן למחוק תכונות ורכיבי משנה אם הם מיותרים.


API פשוט עבור XML (SAX)

SAX הוא מנתח פיתון נוסף, שמתגבר על החסרון של miniDOM על ידי קריאת המסמך ברצף. זה לא טוען את כל העץ לזיכרון שלו, וגם מאפשר לך להשליך פריטים, ומצמצם את השימוש בזיכרון.

ראשית, תן לנו ליצור אובייקט מנתח SAX ולרשום פונקציות callback עבור האירועים השונים שבהם אתה רוצה לטפל במסמך 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"]}')

פלט >>

חבילה: חופשה בפריז

חבילה: הוואי הרפתקאות

חבילה: חופשה איטלקית

חבילה: Andaman Island Retreat

ניתן להשתמש ב-SAX לקבצים גדולים ולסטרימינג בשל היעילות שלו. אבל, זה לא נוח בזמן עבודה עם אלמנטים מקוננים עמוקים. מה אם אתה רוצה לגשת לכל צומת עץ אקראי? מכיוון שהוא אינו תומך בגישה אקראית, המנתח יצטרך לקרוא את כל המסמך ברצף כדי לגשת לרכיב ספציפי.


סנכרן את כל הערכים הכפולים שלך עם Nanonets. שמור על כל החשבונות שלך מאוזנים, 24×7. הגדר את תהליכי החשבונאות שלך תוך פחות מ-15 דקות. ראה כיצד.


זרימת Pull Parser עבור XML

זה pulldom ספריית Python המספקת 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

החזר: כן

חבילה: Andaman Island Retreat

משך זמן: 8

החזר: כן

בדוק את התוצאות! מנתח ה-pull משלב כמה תכונות מ-miniDOM ו-SAX, מה שהופך אותו ליעיל יחסית.

<br> סיכום

אני בטוח שיש לך הבנה טובה של המנתחים השונים הזמינים ב-python עד עכשיו. לדעת מתי לבחור איזה מנתח לחסוך זמן ומשאבים חשובה לא פחות. בין כל המנתחים שראינו, ElementTree מספק תאימות מרבית לביטויי XPath המסייעים בביצוע שאילתות מורכבות. למינידום יש ממשק קל לשימוש וניתן לבחור אותו לטיפול בקבצים קטנים, אך הוא איטי מדי במקרה של קבצים גדולים. במקביל, נעשה שימוש ב-SAX במצבים בהם קובץ ה-XML מתעדכן כל הזמן, כמו במקרה של למידת מכונה בזמן אמת.

חלופה אחת לניתוח הקבצים שלך היא שימוש בכלי ניתוח אוטומטיים כמו Nanonets. Nanonets יכול לעזור לך לחלץ נתונים מכל סוג של מסמך בשניות מבלי לכתוב שורת קוד אחת.

Oלייעל את הביצועים העסקיים שלך, לחסוך בעלויות ולהגביר את הצמיחה. תגלה כיצד מקרי השימוש של Nanonets יכולים לחול על המוצר שלך.


בול זמן:

עוד מ AI & Machine Learning