تجزیه داده های XML تجزیه داده های XML نمونه سازی تجزیه کننده


نویسنده: آرسنی کاپولکین
تاریخ انتشار: 21 سپتامبر 2012
ترجمه: A. Panin
تاریخ ترجمه: 10 نوامبر 2013

معرفی

XML یک زبان نشانه گذاری استاندارد است که دارای مجموعه ای از قوانین برای رمزگذاری اسناد با ساختار سلسله مراتبی به روشی قابل خواندن توسط انسان است. قالب متن. استاندارد XML گسترده شده است و برای تولید اسناد ساده بسیار فشرده (مانند درخواست های SOAP) و اسناد چند گیگابایتی (که توسط پروژه OpenStreetMap استفاده می شود) با وابستگی های داده پیچیده (COLLADA) استفاده می شود. برای پردازش اسناد XML، کاربران معمولاً به یک کتابخانه خاص نیاز دارند: باید یک تجزیه کننده اسناد XML را پیاده سازی کند که سند را از یک سند متنی به یک نمایش داخلی تبدیل کند. استاندارد XML از نظر سرعت تجزیه، خوانایی کاربر، و پیچیدگی کد برای تجزیه یک معامله است - بنابراین، داشتن یک سیستم سریع برای تجزیه اسناد XML ممکن است بر انتخاب ترجیحی XML به عنوان قالب برای ذخیره داده های برنامه تأثیر بگذارد.

این فصل تکنیک های مختلفی را با هدف بهبود عملکرد سیستم تجزیه توصیف شده توصیف می کند و به نویسنده اجازه می دهد تا یک سیستم تجزیه بسیار سازنده را با استفاده از زبان برنامه نویسی C++ توسعه دهد: pugixml. اگرچه این تکنیک‌ها برای سیستم تجزیه اسناد XML استفاده می‌شوند، اما بیشتر آن‌ها می‌توانند برای سیستم‌های تجزیه اسناد با فرمت‌های دیگر یا حتی در اجزای نرم‌افزاری کاملا نامرتبط به کار گرفته شوند (به عنوان مثال، الگوریتم‌های مدیریت حافظه به طور گسترده در سیستم‌های تجزیه نامرتبط استفاده می‌شوند. اسناد متنیمناطق).

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

مدل های سیستم های تجزیه XML

هر کدام از مدل های مختلفسیستم های تجزیه اسناد XML در شرایط خاص بهینه هستند و هر یک از این مدل ها پارامترهای عملکرد و مصرف حافظه خاص خود را دارند. مدل های زیر بیشترین استفاده را دارند:

  • هنگام استفاده از سیستم های تجزیه مبتنی بر SAX (Simple API برای XML)، کاربر در محل خود دریافت می کند جزء نرم افزاری، که انتظار یک جریان داده سند را به عنوان ورودی دارد و چندین عملکرد برگشتی مانند "باز کردن برچسب"، "بستن برچسب"، "شخصیت در داخل تگ" را ارائه می دهد. سیستم تجزیه از توابع پاسخ به تماس هنگام پردازش داده های سند استفاده می کند. زمینه مورد نیاز برای تجزیه توسط عمق درخت عنصر فعلی محدود می شود، که به معنای کاهش قابل توجهی در نیازهای حافظه است. این نوع سیستم تجزیه را می توان برای پردازش اسناد جریانی زمانی که تنها بخشی از سند در یک زمان در دسترس است استفاده کرد.
  • تجزیه کششی از نظر خود فرآیند مشابه تجزیه مبتنی بر SAX است - یک عنصر سند در یک زمان پردازش می شود، اما روش مدیریت فرآیند تجزیه تغییر کرده است: در یک سیستم تجزیه مبتنی بر SAX، فرآیند تجزیه توسط کنترل می شود. خود سیستم با استفاده از توابع پاسخ به تماس، در حالی که در تجزیه کششی، کاربر فرآیند تجزیه را با استفاده از یک شی تکرار کننده کنترل می کند.
  • هنگام استفاده از سیستم‌های تجزیه مبتنی بر DOM (مدل شیء سند)، کاربر یک سند کامل را در قالب یک بافر یا جریانی از داده‌های متنی به سیستم تجزیه ارسال می‌کند، که بر اساس آن سیستم تجزیه یک نمایش شی در حافظه از کل را ایجاد می‌کند. درخت عناصر سند، با استفاده از اشیاء جداگانه برای هر یک عنصر خاص یا ویژگی XML، و همچنین مجموعه ای از عملیات معتبر (به عنوان مثال، "دریافت همه عناصر کودکاین گره"). کتابخانه pugxml از این مدل استفاده می کند.

انتخاب مدل سیستم تجزیه معمولاً به اندازه سند و ساختار آن بستگی دارد. از آنجایی که pugixml بر اساس DOM تجزیه می شود، برای اسنادی که:

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

راه حل های معماری در pugixml

در طول توسعه کتابخانه pugixml، بیشتر تمرکز بر مشکل ایجاد نمایش DOM بود، زیرا اگرچه سیستم‌های تجزیه سریع و سبک وزن مبتنی بر SAX (مانند Expat) در دسترس بودند، همه سیستم‌های تجزیه XML مبتنی بر DOM برای تولید در دسترس بودند. استفاده در زمان ایجاد pugixml (2006) یا خیلی سبک نبود یا خیلی سریع نبود. بر این اساس، هدف اصلی فرآیند توسعه puixml ایجاد یک کتابخانه بسیار سریع و سبک برای انجام دستکاری اسناد XML مبتنی بر DOM است.


انتشار این مقاله تنها با لینک به وب سایت نویسنده مقاله مجاز است

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

هنگام تجزیه فایل های XML بزرگ، دو مشکل پیش می آید:
1. حافظه کافی نیست.
2. زمان کافی برای اجرای اسکریپت اختصاص داده نشده است.

مشکل دوم مربوط به زمان در صورتی که سرور آن را ممنوع نکند قابل حل است.
اما حل مشکل حافظه دشوار است، حتی اگر در مورد سرور خود صحبت کنیم، انتقال فایل های 500 مگابایتی خیلی آسان نیست و به سادگی امکان افزایش حافظه در هاست و VDS وجود ندارد.

PHP چندین گزینه پردازش XML داخلی دارد - SimpleXML، DOM، SAX.
همه این گزینه‌ها در بسیاری از مقالات با مثال‌ها به تفصیل توضیح داده شده‌اند، اما همه نمونه‌ها کار با یک سند کامل XML را نشان می‌دهند.

در اینجا یک مثال است، ما یک شی را از آن دریافت می کنیم فایل XML

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

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

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

تابع webi_xml ($file)
{

########
تابع داده ###

{
چاپ $data ;
}
############################################



{
چاپ $name ;
print_r($attrs);
}


تابع برچسب بستن ##
تابع endElement ($ تجزیه کننده، $name)
{
چاپ $name ;
}
############################################

($xml_parser، "داده");

// فایل را باز کنید
$fp = fopen($file، "r");

$perviy_vxod = 1 ; $data = "" ;



{

$simvol = fgetc ($fp)؛ $data .= $simvol ;


if($simvol != ">" ) (ادامه؛)


پژواک"

زنگ تفريح؛
}

$data = "" ;
}
fclose($fp);

Webi_xml("1.xml");

?>

در این مثال، من همه چیز را در یک تابع ()webi_xml قرار دادم و در پایین آن می توانید فراخوانی آن را ببینید.
خود اسکریپت از سه عملکرد اصلی تشکیل شده است:
1. تابعی که باز شدن تگ startElement() را می گیرد
2. تابعی که تگ بسته شدن endElement() را می گیرد
3. و تابع دریافت داده data() .

فرض کنید محتویات فایل 1.xml یک دستور است



< title >نان ساده
< ingredient amount = "3" unit = "стакан" >ارد
< ingredient amount = "0.25" unit = "грамм" >مخمر
< ingredient amount = "1.5" unit = "стакан" >آب گرم
< ingredient amount = "1" unit = "чайная ложка" >نمک
< instructions >
< step > همه مواد را با هم مخلوط کرده و کاملا ورز دهید.
< step > با یک پارچه بپوشانید و یک ساعت در اتاق گرم بگذارید..
< step > دوباره ورز دهید, روی یک ورقه پخت قرار دهید و در فر قرار دهید.
< step > به سایت سایت مراجعه کنید


ما همه چیز را با فراخوانی تابع کلی webi_xml ("1.xml") شروع می کنیم.
سپس تجزیه کننده در این تابع شروع می شود و همه نام تگ ها را به حروف بزرگ تبدیل می کند تا همه تگ ها دارای حروف یکسان باشند.

$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser، XML_OPTION_CASE_FOLDING، true);

اکنون نشان می‌دهیم که کدام توابع برای باز شدن یک برچسب، بسته شدن و پردازش داده‌ها کار می‌کنند

xml_set_element_handler($xml_parser، "startElement"، "endElement");
xml_set_character_data_handler($xml_parser، "داده");

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

و آن را برای جداساز ارسال کنید
xml_parse ($xml_parser، $data، feof ($fp));
پس از پردازش داده ها، متغیر رشته ریست می شود و دوباره جمع آوری داده ها در یک رشته شروع می شود و رشته برای بار دوم تشکیل می شود.

در مورد سوم
</b><br>در چهارم <br><b>نان ساده

لطفا توجه داشته باشید که یک متغیر رشته همیشه از یک تگ تکمیل شده تشکیل می شود > و لازم نیست مثلاً یک برچسب باز و بسته همراه با داده برای سارق ارسال شود
نان ساده
برای این هندلر مهم است که یک تگ کامل بدون شکست، حداقل یک تگ باز و در مرحله بعد یک تگ بسته دریافت کند یا بلافاصله 1000 خط از یک فایل را دریافت کند، مهم نیست، نکته اصلی این است که تگ مثلاً نمی شکند

le>نان ساده
به این ترتیب، ارسال داده به کنترل کننده غیرممکن است، زیرا برچسب پاره شده است.
شما می توانید روش خود را برای ارسال اطلاعات به هندلر ایجاد کنید، به عنوان مثال، 1 مگابایت داده جمع آوری کنید و برای افزایش سرعت آن را برای کنترل کننده ارسال کنید، فقط مطمئن شوید که برچسب ها همیشه تکمیل شده و داده ها ممکن است پاره شوند.
ساده</b><br><b>نان

بدین ترتیب می توانید در قسمت های دلخواه ارسال کنید فایل بزرگبه کنترل کننده

حال بیایید نحوه پردازش این داده ها و نحوه به دست آوردن آنها را بررسی کنیم.

بیایید با تابع برچسب های باز شروع کنیم startElement ($ تجزیه کننده، $name، $attrs)
بیایید فرض کنیم که پردازش به خط رسیده است
< ingredient amount = "3" unit = "стакан" >ارد
سپس در داخل تابع متغیر $name برابر خواهد بود جزءیعنی نام تگ باز (هنوز به بستن تگ نرسیده است).
همچنین در این حالت، آرایه ای از ویژگی های این تگ $attrs در دسترس خواهد بود که حاوی داده است مقدار = "3" و واحد = "شیشه".

پس از این، داده های تگ باز توسط تابع پردازش شد داده ($Parser، $data)
متغیر $data شامل همه چیزهایی است که بین تگ های باز و بسته است، در مورد ما این متن Muka است.

و پردازش رشته ما توسط تابع به پایان می رسد endElement ($ تجزیه کننده، $name)
این نام تگ بسته است، در مورد ما $name برابر خواهد بود جزء

و بعد از آن دوباره همه چیز در دایره قرار گرفت.

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

تابع webi_xml ($file)
{
جهانی $webi_depth ; // شمارنده برای ردیابی عمق تودرتو
$webi_depth = 0 ;
جهانی $webi_tag_open ; // حاوی آرایه ای از open in خواهد بود این لحظهبرچسب ها
$webi_tag_open = array();
جهانی $webi_data_temp ; // این آرایه حاوی داده های یک تگ خواهد بود

####################################################
تابع داده ###
داده های تابع ($Parser، $data)
{
جهانی $webi_depth ;
جهانی $webi_tag_open ;
جهانی $webi_data_temp ;
// داده ها را به آرایه اضافه کنید که نشان دهنده تگ تودرتو و در حال حاضر باز است
$webi_data_temp [ $webi_depth ][ $webi_tag_open [ $webi_depth ]][ "Data" ].= $data ;
}
############################################

####################################################
### تابع تگ باز
تابع startElement ($parser، $name، $attrs)
{
جهانی $webi_depth ;
جهانی $webi_tag_open ;
جهانی $webi_data_temp ;

// اگر سطح تودرتو دیگر صفر نباشد، یک تگ از قبل باز است
// و داده های آن از قبل در آرایه است، می توانید آن را پردازش کنید
اگر ($webi_depth)
{




" ;

چاپ "
" ;
print_r($webi_tag_open); // آرایه ای از تگ های باز
چاپ "


" ;

// پس از پردازش داده ها، آن را حذف کنید تا حافظه آزاد شود
unset($GLOBALS [ "webi_data_temp" ][$webi_depth ]);
}

// اکنون تگ بعدی باز می شود و در مرحله بعد پردازش بیشتر انجام می شود
$webi_depth++; // افزایش لانه سازی

$webi_tag_open [ $webi_depth ]= $name ; // یک تگ باز به آرایه اطلاعات اضافه کنید
$webi_data_temp [ $webi_depth ][ $name ][ "attrs" ]= $attrs ; // اکنون ویژگی های برچسب را اضافه کنید

}
###############################################

#################################################
تابع برچسب بستن ##
تابع endElement ($ تجزیه کننده، $name) (
جهانی $webi_depth ;
جهانی $webi_tag_open ;
جهانی $webi_data_temp ;

// پردازش داده ها از اینجا شروع می شود، به عنوان مثال افزودن به پایگاه داده، ذخیره در یک فایل و غیره.
// $webi_tag_open شامل زنجیره ای از تگ های باز بر اساس سطح تودرتو است
// برای مثال $webi_tag_open[$webi_depth] حاوی نام تگ باز است که اطلاعات آن در حال حاضر در حال پردازش است.
// سطح تودرتوی تگ $webi_depth
// $webi_data_temp[$webi_depth][$webi_tag_open[$webi_depth]]["attrs"] آرایه‌ای از ویژگی‌های برچسب
// $webi_data_temp[$webi_depth][$webi_tag_open[$webi_depth]]["data"] داده برچسب

چاپ "داده". $webi_tag_open [ $webi_depth ]. "--" .($webi_data_temp [$webi_depth ][$webi_tag_open [$webi_depth]][ "داده"]). "
" ;
print_r ($webi_data_temp [$webi_depth ][$webi_tag_open [$webi_depth]][ "attrs" ]);
چاپ "
" ;
print_r($webi_tag_open);
چاپ "


" ;

Unset($GLOBALS [ "webi_data_temp" ]); // پس از پردازش داده ها، کل آرایه را با داده ها حذف می کنیم، زیرا تگ بسته شده است
unset($GLOBALS [ "webi_tag_open" ][$webi_depth ]); // اطلاعات مربوط به این تگ باز را حذف کنید... از زمانی که بسته شد

$webi_depth --; // کاهش لانه سازی
}
############################################

$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser، XML_OPTION_CASE_FOLDING، true);

// نشان می دهد که کدام توابع هنگام باز کردن و بستن تگ ها کار می کنند
xml_set_element_handler($xml_parser، "startElement"، "endElement");

// یک تابع برای کار با داده ها را مشخص کنید
xml_set_character_data_handler($xml_parser، "داده");

// فایل را باز کنید
$fp = fopen($file، "r");

$perviy_vxod = 1 ; // برای بررسی اولین ورودی به فایل پرچم گذاری کنید
$data = "" ; // در اینجا داده ها را از فایل به صورت قسمتی جمع آوری کرده و به تجزیه کننده xml ارسال می کنیم

// حلقه بزنید تا انتهای فایل پیدا شود
در حالی که (! feof ($fp ) و $fp )
{
$simvol = fgetc ($fp)؛ // یک کاراکتر از فایل را بخوانید
$data .= $simvol ; // این کاراکتر را به داده های ارسالی اضافه کنید

// اگر کاراکتر تگ پایانی نیست، به ابتدای حلقه برگردید و یک کاراکتر دیگر به داده ها اضافه کنید و به همین ترتیب تا زمانی که تگ پایان پیدا شود.
if($simvol != ">" ) (ادامه؛)
// اگر تگ بسته پیدا شد، اکنون این داده های جمع آوری شده را برای پردازش ارسال می کنیم

// بررسی کنید که آیا این اولین ورودی به فایل است یا خیر، سپس هر چیزی را که قبل از تگ است حذف می کنیم// زیرا گاهی اوقات ممکن است قبل از شروع XML با زباله مواجه شوید (ویرایشگران دست و پا چلفتی، یا فایل توسط یک اسکریپت از سرور دیگری دریافت شده است)
if($perviy_vxod ) ($data = strstr ($data, "

// اکنون داده ها را به تجزیه کننده xml بیاندازید
if (! xml_parse ($xml_parser، $data، feof ($fp))) (

// در اینجا می توانید خطاهای اعتبار را پردازش و دریافت کنید...
// به محض بروز خطا، تجزیه متوقف می شود
پژواک"
خطای XML: ". xml_error_string(xml_get_error_code($xml_parser));
پژواک "در خط" . xml_get_current_line_number ($xml_parser);
زنگ تفريح؛
}

// پس از تجزیه، داده های جمع آوری شده را برای مرحله بعدی چرخه دور بریزید.
$data = "" ;
}
fclose($fp);
xml_parser_free ($xml_parser);
// حذف متغیرهای سراسری
unset($GLOBALS [ "webi_depth" ]);
unset($GLOBALS [ "webi_tag_open" ]);
unset($GLOBALS [ "webi_data_temp" ]);

Webi_xml("1.xml");

?>

کل مثال با نظرات همراه است، اکنون تست و آزمایش کنید.
لطفاً توجه داشته باشید که در عملکرد کار با داده ها، داده ها به سادگی در یک آرایه درج نمی شوند، بلکه با استفاده از " اضافه می شوند. .=" از آنجایی که ممکن است داده ها به طور کامل وارد نشوند، و اگر فقط یک تکلیف انجام دهید، هر از گاهی داده ها را به صورت تکه ای دریافت خواهید کرد.

خوب، این همه چیز است، اکنون هنگام پردازش یک فایل با هر اندازه، حافظه کافی وجود دارد، اما زمان اجرای اسکریپت را می توان به چندین روش افزایش داد.
یک تابع در ابتدای اسکریپت وارد کنید
set_time_limit(6000);
یا
ini_set ("max_execution_time" , "6000");

یا متنی را به فایل htaccess اضافه کنید
php_value max_execution_time 6000

این مثال ها زمان اجرای اسکریپت را به 6000 ثانیه افزایش می دهد.
تنها زمانی که حالت ایمن خاموش باشد می توانید زمان را از این طریق افزایش دهید.

اگر به ویرایش php.ini دسترسی دارید، می توانید زمان استفاده را افزایش دهید
max_execution_time = 6000

به عنوان مثال، در هاست مستر هاست، در زمان نگارش این مقاله، افزایش زمان اسکریپت ممنوع است، علی رغم حالت امن، اما اگر حرفه ای هستید، می توانید php خود را بر روی masterhost بسازید، اما این در این مقاله نیست.

تجزیه XML اساساً به معنای عبور از یک سند XML و برگرداندن داده های مربوطه است. و اگرچه تعداد فزاینده ای از خدمات وب داده ها را به فرمت JSONاما بیشتر آنها هنوز از XML استفاده می کنند، بنابراین اگر می خواهید از محدوده کامل استفاده کنید، تسلط بر تجزیه XML مهم است رابط های موجود API.

با استفاده از پسوند SimpleXMLدر PHP که دوباره در PHP 5.0 اضافه شد، کار با XML بسیار آسان و ساده است. در این مقاله به شما نشان خواهم داد که چگونه این کار را انجام دهید.

مبانی استفاده

بیایید با مثال زیر شروع کنیم languages.xml:


>

> 1972>
> دنیس ریچی >
>

> 1995>
> راسموس لردورف >
>

> 1995>
> جیمز گاسلینگ >
>
>

این سند XML حاوی لیستی از زبان های برنامه نویسی با اطلاعاتی در مورد هر زبان است: سال معرفی و نام سازنده آن.

اولین قدم این است که XML را با استفاده از توابع بارگیری کنید simplexml_load_file()، یا simplexml_load_string(). همانطور که از نام توابع پیداست، توابع اول XML را از یک فایل بارگذاری می کند و دومی XML را از یک رشته بارگذاری می کند.

هر دو تابع کل درخت DOM را در حافظه می خوانند و یک شی را برمی گردانند SimpleXMLElement. در مثال بالا، شی در متغیر $languages ​​ذخیره می شود. می توانید از توابع استفاده کنید var_dump()یا print_r()برای دریافت جزئیات در مورد شیء برگشتی در صورت تمایل.

SimpleXMLElement Object
[lang] => آرایه
[ 0 ] => SimpleXMLElement Object
[@attributes] => آرایه
[نام] => سی
[ظاهر شد] => 1972
[خالق] => دنیس ریچی
[ 1 ] => SimpleXMLElement Object
[@attributes] => آرایه
[نام] => PHP
[ظاهر شد] => 1995
[خالق] => راسموس لردورف
[ 2 ] => SimpleXMLElement Object
[@attributes] => آرایه
[نام] => جاوا
[ظاهر شد] => 1995
[خالق] => جیمز گاسلینگ
)
)

این XML حاوی یک عنصر ریشه است زبان ها، که در داخل آن سه عنصر وجود دارد زبانهر عنصر آرایه مربوط به یک عنصر است زباندر سند XML

با استفاده از عملگر می توانید به خصوصیات یک شی دسترسی پیدا کنید -> . برای مثال، $languages->lang یک شی SimpleXMLElement را به شما برمی گرداند که با عنصر اول مطابقت دارد. زبان. این شی شامل دو ویژگی ظاهر شده و خالق است.

$languages ​​-> lang [ 0 ] -> ظاهر شد ;
$languages ​​-> lang [ 0 ] -> creator ;

نمایش لیستی از زبان ها و نشان دادن ویژگی های آنها را می توان به راحتی با استفاده از یک حلقه استاندارد مانند برای هر.

foreach ($languages ​​-> lang as $lang ) (
printf(
"" ,
$lang [ "name" ] ,
$lang -> ظاهر شد،
$lang -> خالق
) ;
}

توجه کنید که چگونه به نام ویژگی lang عنصر برای دریافت نام زبان دسترسی پیدا کردم. به این ترتیب می توانید به هر ویژگی عنصری که به عنوان یک شی SimpleXMLElement نشان داده شده است دسترسی پیدا کنید.

کار با فضاهای نام

در حین کار با XML سرویس های مختلف وب، بیش از یک بار با فضاهای نام عناصر روبرو خواهید شد. بیایید خودمان را تغییر دهیم languages.xmlبرای نشان دادن مثالی از استفاده از فضای نام:



xmlns:dc =>

> 1972>
> دنیس ریچی >
>

> 1995>
> راسموس لردورف >
>

> 1995>
> جیمز گاسلینگ >
>
>

حالا عنصر ایجاد کنندهدر فضای نام قرار می گیرد دی سیکه به http://purl.org/dc/elements/1.1/ اشاره می کند. اگر سعی کنید با استفاده از کد قبلی ما، سازندگان زبان را چاپ کنید، کار نخواهد کرد. برای خواندن فضای نام عناصر باید از یکی از روش های زیر استفاده کنید.

اولین رویکرد استفاده از نام های URI به طور مستقیم در کد هنگام دسترسی به فضای نام عنصر است. مثال زیر نحوه انجام این کار را نشان می دهد:

$dc = $languages ​​-> lang [ 1 ] - > children( "http://purl.org/dc/elements/1.1/") ;
echo $dc -> creator ;

روش فرزندان()یک فضای نام می گیرد و عناصر فرزند را که با یک پیشوند شروع می شوند برمی گرداند. دو آرگومان نیاز دارد که اولی فضای نام XML است و دومی یک آرگومان اختیاری است که به طور پیش فرض نادرست. اگر آرگومان دوم روی TRUE تنظیم شود، فضای نام به عنوان یک پیشوند در نظر گرفته می شود. اگر FALSE باشد، فضای نام به عنوان فضای نام URL در نظر گرفته می شود.

روش دوم خواندن نام‌های URI از سند و استفاده از آنها هنگام دسترسی به فضای نام عنصر است. این در واقع راه بهتری برای دسترسی به عناصر است زیرا نیازی نیست که به URI کدگذاری شده باشید.

$namespaces = $languages ​​-> getNamespaces (true) ;
$dc = $languages ​​-> lang [ 1 ] -> children ( ($namespace [ "dc" ] );

echo $dc -> creator ;

روش GetNamespaces()آرایه ای از نام های پیشوند و URI های مرتبط با آنها را برمی گرداند. یک پارامتر اضافی را می پذیرد که به طور پیش فرض به آن می رسد نادرست. اگر شما آن را مانند درست است، واقعی، سپس این روش نام های استفاده شده در گره های والد و فرزند را برمی گرداند. در غیر این صورت، فضاهای نام مورد استفاده را فقط در گره والد پیدا می کند.

اکنون می توانید از طریق لیست زبان ها مانند این موارد را تکرار کنید:

$languages ​​= simplexml_load_file ("languages.xml" );
$ns = $languages ​​-> getNamespaces (true) ;

foreach ($languages ​​-> lang as $lang ) (
$dc = $lang -> Children ($ns [ "dc" ] );
printf(
"

%s در %d ظاهر شد و توسط %s ایجاد شد.

" ,
$lang [ "name" ] ,
$lang -> ظاهر شد،
$dc -> خالق
) ;
}

مثال عملی - تجزیه یک کانال ویدیویی از YouTube

بیایید به مثالی نگاه کنیم که یک فید RSS از یک کانال YouTube دریافت می‌کند و پیوندهایی به تمام ویدیوهای آن را نمایش می‌دهد. برای انجام این کار با آدرس زیر تماس حاصل فرمایید:

http://gdata.youtube.com/feeds/api/users/xxx/uploads

URL فهرستی از آخرین ویدیوها را از یک کانال معین در قالب XML برمی گرداند. ما XML را تجزیه می کنیم و اطلاعات زیر را برای هر ویدیو دریافت می کنیم:

  • پیوند به ویدیو
  • مینیاتور
  • نام

ما با جستجو و بارگذاری XML شروع می کنیم:

$channel = "Channel_name" ;
$url = "http://gdata.youtube.com/feeds/api/users/". کانال $. "/uploads" ;
$xml = file_get_contents ($url);

$feed = simplexml_load_string ($xml) ;
$ns = $feed -> getNameSpaces ( true ) ;

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

>

>



عنوان… >

>

>

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

foreach ($feed -> ورودی به عنوان $entry ) (
$group = $entry -> children ($ns [ "رسانه" ] ;
$group = $group -> group ;
$thumbnail_attrs = $group -> thumbnail [ 1 ] -> ویژگیها () ;
$image = $thumbnail_attrs [ "url" ] ;
$player = $group -> player -> ویژگی‌ها () ;
$link = $player [ "url" ] ;
$title = $group -> title ;
printf( "

" ,
$player، $image، $title)؛
}

نتیجه

اکنون که می دانید چگونه از آن استفاده کنید SimpleXMLبرای تجزیه داده های XML، می توانید مهارت های خود را با تجزیه فیدهای XML مختلف با API های مختلف بهبود بخشید. اما مهم است که در نظر بگیرید که SimpleXML کل DOM را در حافظه می خواند، بنابراین اگر در حال تجزیه یک مجموعه داده بزرگ هستید، ممکن است حافظه شما تمام شود. برای کسب اطلاعات بیشتر در مورد SimpleXML مستندات را بخوانید.


اگر سوالی دارید، توصیه می کنیم از ما استفاده کنید