سؤال

لدى بايثون عدة طرق لتحليل XML...

أنا أفهم أساسيات التحليل ساكس.وهو يعمل كمحلل دفق، مع واجهة برمجة تطبيقات تعتمد على الأحداث.

انا افهم ال DOM المحلل اللغوي أيضا.يقرأ XML في الذاكرة ويحوله إلى كائنات يمكن الوصول إليها باستخدام Python.

بشكل عام، كان من السهل الاختيار بين الاثنين اعتمادًا على ما تحتاج إلى القيام به، وقيود الذاكرة، والأداء، وما إلى ذلك.

(آمل أن أكون على صواب حتى الآن.)

منذ إصدار Python 2.5، أصبح لدينا أيضًا ElementTree.كيف يمكن مقارنة هذا بـ DOM وSAX؟ما هو أكثر مماثلة ل؟لماذا هو أفضل من المحللين السابقين؟

هل كانت مفيدة؟

المحلول

يعتبر ElementTree أسهل بكثير في الاستخدام، لأنه يمثل شجرة XML (بشكل أساسي) كبنية من القوائم، ويتم تمثيل السمات كقواميس.

يحتاج ElementTree إلى ذاكرة أقل بكثير لأشجار XML مقارنة بـ DOM (وبالتالي فهو أسرع)، ويحتاج التحليل الزائد عبر iterparse يمكن مقارنته بـ SAX.بالإضافة إلى ذلك، iterparse تقوم بإرجاع بنيات جزئية، ويمكنك الحفاظ على ثبات استخدام الذاكرة أثناء التحليل عن طريق تجاهل البنيات بمجرد معالجتها.

يحتوي ElementTree، كما هو الحال في Python 2.5، على مجموعة ميزات صغيرة فقط مقارنة بمكتبات XML الكاملة، ولكنها كافية للعديد من التطبيقات.إذا كنت بحاجة إلى محلل للتحقق أو دعم XPath الكامل، فإن lxml هو الحل الأمثل.لفترة طويلة، كان غير مستقر تمامًا، لكن لم أواجه أي مشاكل معه منذ الإصدار 2.1.

يختلف ElementTree عن DOM، حيث تتمتع العقد بإمكانية الوصول إلى الوالدين والأشقاء.يعد التعامل مع المستندات الفعلية بدلاً من مخازن البيانات أمرًا مرهقًا بعض الشيء، لأن العقد النصية لا يتم التعامل معها على أنها عقد فعلية.في مقتطف XML

<a>This is <b>a</b> test</a>

السلسلة test سيكون ما يسمى tail من العنصر b.

بشكل عام، أوصي بـ ElementTree كإعداد افتراضي لجميع عمليات معالجة XML باستخدام Python، وDOM أو SAX كحلول لمشاكل معينة.

نصائح أخرى

الحد الأدنى من تنفيذ DOM:

وصلة.

توفر Python تطبيقًا كاملاً وفقًا لمعايير W3C لـ XML DOM (xml.dom) والحد الأدنى ، xml.dom.minidom.هذا الأخير أبسط وأصغر من التنفيذ الكامل.ومع ذلك، من "منظور التحليل"، فهو يحتوي على جميع إيجابيات وسلبيات DOM القياسي - أي.يقوم بتحميل كل شيء في الذاكرة.

النظر في ملف XML الأساسي:

<?xml version="1.0"?>
<catalog>
    <book isdn="xxx-1">
      <author>A1</author>
      <title>T1</title>
    </book>
    <book isdn="xxx-2">
      <author>A2</author>
      <title>T2</title>
    </book>
</catalog>

محلل بايثون محتمل يستخدم minidom يكون:

import os
from xml.dom import minidom
from xml.parsers.expat import ExpatError

#-------- Select the XML file: --------#
#Current file name and directory:
curpath = os.path.dirname( os.path.realpath(__file__) )
filename = os.path.join(curpath, "sample.xml")
#print "Filename: %s" % (filename)

#-------- Parse the XML file: --------#
try:
    #Parse the given XML file:
    xmldoc = minidom.parse(filepath)
except ExpatError as e:
    print "[XML] Error (line %d): %d" % (e.lineno, e.code)
    print "[XML] Offset: %d" % (e.offset)
    raise e
except IOError as e:
    print "[IO] I/O Error %d: %s" % (e.errno, e.strerror)
    raise e
else:
    catalog = xmldoc.documentElement
    books = catalog.getElementsByTagName("book")

    for book in books:
        print book.getAttribute('isdn')
        print book.getElementsByTagName('author')[0].firstChild.data
        print book.getElementsByTagName('title')[0].firstChild.data

لاحظ أن xml.parsers.expat هي واجهة Python لمحلل XML غير المعتمد من Expat (docs.python.org/2/library/pyexpat.html).

ال xml.dom توفر الحزمة أيضًا فئة الاستثناء DOMEException, ، ولكن لا يتم تناوله في minidom!

واجهة برمجة تطبيقات ElementTree XML:

وصلة.

ElementTree أسهل بكثير في الاستخدام ويتطلب ذاكرة أقل من XML DOM.علاوة على ذلك، يتوفر تطبيق C (xml.etree.cElementTree).

محلل بايثون محتمل يستخدم ElementTree يكون:

import os
from xml.etree import cElementTree  # C implementation of xml.etree.ElementTree
from xml.parsers.expat import ExpatError  # XML formatting errors

#-------- Select the XML file: --------#
#Current file name and directory:
curpath = os.path.dirname( os.path.realpath(__file__) )
filename = os.path.join(curpath, "sample.xml")
#print "Filename: %s" % (filename)

#-------- Parse the XML file: --------#
try:
    #Parse the given XML file:
    tree = cElementTree.parse(filename)
except ExpatError as e:
    print "[XML] Error (line %d): %d" % (e.lineno, e.code)
    print "[XML] Offset: %d" % (e.offset)
    raise e
except IOError as e:
    print "[XML] I/O Error %d: %s" % (e.errno, e.strerror)
    raise e
else:
    catalogue = tree.getroot()

    for book in catalogue:
        print book.attrib.get("isdn")
        print book.find('author').text
        print book.find('title').text

إن parse () الخاص بـ ElementTree يشبه DOM، في حين أن iterparse () يشبه SAX.في رأيي، ElementTree أفضل من DOM وSAX لأنه يوفر واجهة برمجة تطبيقات (API) أسهل في العمل معها.

يحتوي ElementTree على واجهة برمجة تطبيقات أكثر بيثونية.وهو موجود أيضًا في المكتبة القياسية الآن، لذا فإن استخدامه يقلل من التبعيات.

أنا أفضل فعلا com.lxml لأنه يحتوي على واجهة برمجة تطبيقات مثل ElementTree، ولكنه يحتوي أيضًا على ميزات إضافية رائعة ويعمل بشكل جيد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top