xml.dom.minidom --- پیادهسازی کمینهی DOM¶
کد منبع: Lib/xml/dom/minidom.py
xml.dom.minidom یک پیادهسازی حداقلی از رابط مدل شیء سند (DOM) با API مشابه زبانهای دیگر است. این پیادهسازی بهگونهای در نظر گرفته شده است که سادهتر از DOM کامل و همچنین بهطور قابلتوجهی کوچکتر باشد. کاربرانی که از قبل با DOM مهارت ندارند، بهتر است بهجای آن برای پردازش XML خود از ماژول xml.etree.ElementTree استفاده کنند.
توجه
اگر نیاز دارید دادههای غیرقابلاعتماد یا احراز هویتنشده را تجزیه کنید، به امنیت XML مراجعه کنید.
برنامههای DOM معمولاً با تجزیهی مقداری XML به یک DOM آغاز میشوند. با xml.dom.minidom، این کار از طریق توابع parse انجام میشود:
from xml.dom.minidom import parse, parseString
dom1 = parse('c:\\temp\\mydata.xml') # parse an XML file by name
datasource = open('c:\\temp\\mydata.xml')
dom2 = parse(datasource) # parse an open file
dom3 = parseString('<myxml>Some data<empty/> some more data</myxml>')
تابع parse() میتواند یک نام پرونده یا یک شیء پرونده باز را دریافت کند.
- xml.dom.minidom.parse(filename_or_file, parser=None, bufsize=None)¶
یک
Documentاز ورودی دادهشده برمیگرداند. filename_or_file میتواند یک نام پرونده یا یک شیء شبهپرونده باشد. parser، در صورت داده شدن، باید یک شیء پارسر SAX2 باشد. این تابع هندلر سند (document handler) پارسر را تغییر میدهد و پشتیبانی از فضای نام را فعال میکند؛ سایر پیکربندیهای پارسر (مانند تنظیم حلکننده موجودیت (entity resolver)) باید از قبل انجام شده باشند.
اگر XML را در یک رشته دارید، میتوانید بهجای آن از تابع parseString() استفاده کنید:
- xml.dom.minidom.parseString(string, parser=None)¶
یک
Documentبرمیگرداند که رشته را نشان میدهد. این متد یک شیءio.StringIOبرای رشته ایجاد میکند و آن را بهparse()میفرستد.
هر دو تابع یک شیء Document برمیگردانند که نشاندهنده محتوای سند است.
کاری که توابع parse() و parseString() انجام میدهند، اتصال یک پارسر XML به یک «سازنده DOM» (DOM builder) است که میتواند رویدادهای تجزیه را از هر پارسر SAX بپذیرد و آنها را به یک درخت DOM تبدیل کند. نام این توابع شاید گمراهکننده باشد، اما هنگام یادگیری رابطها بهآسانی قابلدرک هستند. تجزیه سند پیش از بازگشت این توابع کامل میشود؛ صرفاً این توابع خود پیادهسازی پارسری ارائه نمیدهند.
همچنین میتوانید با فراخوانی یک متد روی یک شیء «پیادهسازی DOM»، یک Document ایجاد کنید. میتوانید این شیء را با فراخوانی تابع getDOMImplementation() در بسته xml.dom یا ماژول xml.dom.minidom دریافت کنید. هنگامی که یک Document داشتید، میتوانید گرههای فرزند را برای پر کردن DOM به آن اضافه کنید:
from xml.dom.minidom import getDOMImplementation
impl = getDOMImplementation()
newdoc = impl.createDocument(None, "some_tag", None)
top_element = newdoc.documentElement
text = newdoc.createTextNode('Some textual content.')
top_element.appendChild(text)
هنگامی که یک شیء سند DOM داشته باشید، میتوانید از طریق ویژگیها و متدهای آن به بخشهای سند XML خود دسترسی پیدا کنید. این ویژگیها در مشخصات DOM تعریف شدهاند. ویژگی اصلی شیء سند، ویژگی documentElement است. این ویژگی، المان اصلی سند XML را در اختیار شما قرار میدهد: المانی که همهی سایر المانها را در بر دارد. در اینجا یک برنامه نمونه آمده است:
dom3 = parseString("<myxml>Some data</myxml>")
assert dom3.documentElement.tagName == "myxml"
هنگامی که کارتان با یک درخت DOM به پایان رسید، میتوانید بهاختیار متد unlink() را برای تشویق پاکسازی زودهنگام اشیایی که دیگر مورد نیاز نیستند فراخوانی کنید. unlink() یک افزونهی خاص xml.dom.minidom برای DOM API است که گره و نوادگان آن را عملاً بیاستفاده میکند. در غیر این صورت، زبالهروبی پایتون در نهایت اشیاء موجود در درخت را آزاد خواهد کرد.
همچنین ملاحظه نمائید
- مشخصات سطح ۱ مدل شیء سند (DOM)
توصیهنامهی W3C برای DOM که توسط
xml.dom.minidomپشتیبانی میشود.
اشیای DOM¶
تعریف API DOM برای پایتون بهعنوان بخشی از مستندات ماژول xml.dom ارائه شده است. این بخش تفاوتهای بین API و xml.dom.minidom را فهرست میکند.
- Node.unlink()¶
ارجاعهای داخلی درون DOM را قطع کنید تا در نسخههای پایتون بدون زبالهروبی چرخهای، زبالهروبی شود. حتی زمانی که زبالهروبی چرخهای در دسترس است، استفاده از این میتواند مقادیر زیادی حافظه را زودتر در دسترس قرار دهد، بنابراین فراخوانی این روی اشیای DOM به محض اینکه دیگر نیازی به آنها نیست، روش خوبی است. فقط لازم است این روی شیء
Documentفراخوانی شود، اما میتوان آن را روی گرههای فرزند نیز فراخوانی کرد تا فرزندان آن گره حذف شوند.میتوانید با استفاده از دستور
withاز فراخوانی صریح این متد اجتناب کنید. کد زیر هنگام خروج از بلوکwith، بهطور خودکار پیوند dom را قطع میکند:with xml.dom.minidom.parse(datasource) as dom: ... # Work with dom.
- Node.writexml(writer, indent='', addindent='', newl='', encoding=None, standalone=None)¶
XML را در شیء نویسنده بنویسید. نویسنده ورودی را بهصورت متن دریافت میکند، نه بایت؛ باید متد
write()داشته باشد که با متد موجود در رابط شیء پرونده مطابقت دارد. پارامتر indent تورفتگی گره جاری است. پارامتر addindent تورفتگی افزایشی است که برای زیرگرههای گره جاری استفاده میشود. پارامتر newl رشتهای را مشخص میکند که برای پایان دادن به سطرهای جدید استفاده میشود.برای گره
Document، میتوان از یک آرگومان کلیدواژهای اضافی به نام encoding برای مشخص کردن فیلد کدگذاری سرآیند XML استفاده کرد.بهطور مشابه، ذکر صریح آرگومان standalone باعث میشود اعلامیههای مستقل سند به پیشدرآمد سند XML افزوده شوند. اگر مقدار به
Trueتنظیم شود،standalone="yes"افزوده میشود، در غیر این صورت مقدار به"no"تنظیم میشود. ذکر نکردن آرگومان، اعلامیه را از سند حذف میکند.تغییر یافته در نسخهی 3.8: متد
writexml()اکنون ترتیب صفتهایی را که کاربر تعیین کرده است حفظ میکند.تغییر یافته در نسخهی 3.9: پارامتر standalone افزوده شد.
- Node.toxml(encoding=None, standalone=None)¶
یک رشته یا رشته بایتی حاوی XML بازنماییشده توسط گره DOM را برمیگرداند.
با یک آرگومان encoding [1] صریح، نتیجه یک رشته بایت با کدگذاری مشخص است. بدون آرگومان encoding، نتیجه یک رشته یونیکد است و اعلامیه XML در رشته حاصل، کدگذاری را مشخص نمیکند. کدگذاری این رشته با کدگذاری غیر از UTF-8 احتمالاً نادرست است، زیرا UTF-8 کدگذاری پیشفرض XML است.
آرگومان standalone دقیقاً مانند
writexml()رفتار میکند.تغییر یافته در نسخهی 3.8: متد
toxml()اکنون ترتیب ویژگیها را همانطور که کاربر تعیین کرده است حفظ میکند.تغییر یافته در نسخهی 3.9: پارامتر standalone افزوده شد.
- Node.toprettyxml(indent='\t', newl='\n', encoding=None, standalone=None)¶
یک نسخهی زیبانویسیشده از سند برمیگرداند. indent رشتهی تورفتگی را مشخص میکند و پیشفرض آن یک نویسهی تب است؛ newl رشتهای را که در پایان هر خط درج میشود مشخص میکند و پیشفرض آن
\nاست.آرگومان encoding مانند آرگومان متناظر در
toxml()رفتار میکند.آرگومان standalone دقیقاً مانند
writexml()رفتار میکند.تغییر یافته در نسخهی 3.8: متد
toprettyxml()اکنون ترتیب ویژگیهای تعیینشده توسط کاربر را حفظ میکند.تغییر یافته در نسخهی 3.9: پارامتر standalone افزوده شد.
مثال DOM¶
این برنامه نمونه، مثال نسبتاً واقعگرایانهای از یک برنامه ساده است. در این مورد خاص، از انعطافپذیری DOM استفاده چندانی نمیکنیم.
import xml.dom.minidom
document = """\
<slideshow>
<title>Demo slideshow</title>
<slide><title>Slide title</title>
<point>This is a demo</point>
<point>Of a program for processing slides</point>
</slide>
<slide><title>Another demo slide</title>
<point>It is important</point>
<point>To have more than</point>
<point>one slide</point>
</slide>
</slideshow>
"""
dom = xml.dom.minidom.parseString(document)
def getText(nodelist):
rc = []
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
rc.append(node.data)
return ''.join(rc)
def handleSlideshow(slideshow):
print("<html>")
handleSlideshowTitle(slideshow.getElementsByTagName("title")[0])
slides = slideshow.getElementsByTagName("slide")
handleToc(slides)
handleSlides(slides)
print("</html>")
def handleSlides(slides):
for slide in slides:
handleSlide(slide)
def handleSlide(slide):
handleSlideTitle(slide.getElementsByTagName("title")[0])
handlePoints(slide.getElementsByTagName("point"))
def handleSlideshowTitle(title):
print(f"<title>{getText(title.childNodes)}</title>")
def handleSlideTitle(title):
print(f"<h2>{getText(title.childNodes)}</h2>")
def handlePoints(points):
print("<ul>")
for point in points:
handlePoint(point)
print("</ul>")
def handlePoint(point):
print(f"<li>{getText(point.childNodes)}</li>")
def handleToc(slides):
for slide in slides:
title = slide.getElementsByTagName("title")[0]
print(f"<p>{getText(title.childNodes)}</p>")
handleSlideshow(dom)
minidom و استاندارد DOM¶
ماژول xml.dom.minidom اساساً یک DOM سازگار با DOM 1.0 است که برخی ویژگیهای DOM 2 (عمدتاً ویژگیهای فضای نام) را دارد.
استفاده از رابط DOM در پایتون ساده است. قواعد نگاشت زیر اعمال میشوند:
رابطها از طریق اشیای نمونه قابل دسترسی هستند. برنامهها نباید خودشان کلاسها را نمونهسازی کنند؛ باید از توابع سازنده موجود در شیء
Documentاستفاده کنند. رابطهای مشتقشده از تمام عملیات (و ویژگیها)ی رابطهای پایه، بههمراه هر عملیات جدیدی پشتیبانی میکنند.از عملیاتها بهعنوان متد استفاده میشود. از آنجا که DOM فقط از پارامترهای
inاستفاده میکند، آرگومانها با ترتیب معمول (از چپ به راست) ارسال میشوند. هیچ آرگومان اختیاری وجود ندارد. عملیاتهایvoid،Noneرا برمیگردانند.ویژگیهای IDL به ویژگیهای نمونه نگاشت میشوند. برای سازگاری با نگاشت زبان OMG IDL برای پایتون، میتوان به ویژگی
fooاز طریق متدهای دسترسیدهنده_get_foo()و_set_foo()نیز دسترسی داشت. ویژگیهایreadonlyنباید تغییر داده شوند؛ این موضوع در رانتایم اعمال نمیشود.انواع
short int،unsigned int،unsigned long longوbooleanهمگی به اشیاء عدد صحیح پایتون نگاشت میشوند.نوع
DOMStringبه رشتههای پایتون نگاشت میشود.xml.dom.minidomاز بایتها یا رشتهها پشتیبانی میکند، اما بهطور معمول رشتهها را تولید میکند. مقادیر از نوعDOMStringممکن است در مواردی که مشخصه DOM از W3C اجازه داشتن مقدارnullدر IDL را بدهد،Noneنیز باشند.اعلانهای
constبه متغیرهایی در محدودهی مربوط به خود نگاشت میشوند (برای مثالxml.dom.minidom.Node.PROCESSING_INSTRUCTION_NODE)؛ این متغیرها نباید تغییر کنند.DOMExceptionدر حال حاضر درxml.dom.minidomپشتیبانی نمیشود. در عوض،xml.dom.minidomاز استثناهای استاندارد پایتون مانندTypeErrorوAttributeErrorاستفاده میکند.Each of the
NodeListandNamedNodeMapinterfaces has two implementations, which provide additional methods and operations.childNodesis a subclass oflist, or, for nodes which cannot have children, a subclass oftuple. It supports iteration, concatenation, indexing and slicing.attributessupportslen(), theinoperator, subscription by a name or by a(namespaceURI, localName)tuple, assignment and deletion, and the methodsget(),keys(),keysNS(),values(),items()anditemsNS().entitiesandnotationsare read-only and support onlylen()and subscription by a name.strictErrorCheckingandspecifiedare alwaysFalse.removeAttribute()andremoveAttributeNS()raiseNotFoundErrif there is no matching attribute, while the DOM specifies that this has no effect.
رابطهای زیر در xml.dom.minidom پیادهسازی ندارند:
DOMTimeStampEntityReference
بیشتر اینها اطلاعاتی در سند XML را بازتاب میدهند که برای بیشتر کاربران DOM کاربرد عمومی ندارد.
پانویسها