PHP و XML: تجزیه گرهای Expat و DOM

16 مرداد 1398
درسنامه درس 27 از سری آموزش PHP 7
PHP و XML: تجزیه گر های Expat و DOM

تجزیه گر Expat

تجزیه گر Expat ما را قادر می سازد که اسناد یا فایل های XML را PHP پردازش کنیم. این تجزیه گر یک تجزیه گر رویداد-محور است. به این تکه XML نگاه کنید:

<from>Jani</from>

تجزیه گر های رویداد-محور این کد XML را در سه مرحله گزارش می دهند:

  • تشکیل عنصر: from
  • تشکیل قسمت CDATA و مقدار: Jani
  • بستن عنصر: from

بنابراین فرض کنید فایل note.xml را با محتوای زیر داشته باشیم:

<?xml version="1.0" encoding="UTF-8"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

ما می خواهیم از این فایل در مثال های خود استفاده کنیم.

اگر بخواهیم تجزیه گر Expat را راه اندازی کنیم چند handler برای رویدادهای XML تعریف کنید و سپس فایل XML را تجزیه کنید:

<!DOCTYPE html>
<html>
<body>

<?php
//Initialize the XML parser
$parser=xml_parser_create();

//Function to use at the start of an element
function start($parser,$element_name,$element_attrs) {
    switch($element_name) {
        case "NOTE":
        echo "-- Note --<br>";
    break;
        case "TO":
        echo "To: ";
    break;
        case "FROM":
        echo "From: ";
    break;
        case "HEADING":
        echo "Heading: ";
    break;
        case "BODY":
        echo "Message: ";
    }
}

//Function to use at the end of an element
function stop($parser,$element_name) {
    echo "<br>";
}

//Function to use when finding character data
function char($parser,$data) {
    echo $data;
}

//Specify element handler
xml_set_element_handler($parser,"start","stop");

//Specify data handler
xml_set_character_data_handler($parser,"char");

//Open XML file
$fp=fopen("note.xml","r");

//Read data
while ($data=fread($fp,4096)) {
    xml_parse($parser,$data,feof($fp)) or 
    die (sprintf("XML Error: %s at line %d", 
    xml_error_string(xml_get_error_code($parser)),
    xml_get_current_line_number($parser)));
}

//Free the XML parser
xml_parser_free($parser);
?>

</body>
</html>

مشاهده ی خروجی

توضیح مثال:

  • ابتدا با استفاده از تابع ()xml_parser_create تجزیه گر را راه اندازی می کنیم.
  • سپس توابع مختلفی برای کار با event handler ها ساخته ایم.
  • تابع ()xml_set_element_handler را اضافه کرده ایم تا مشخص کنیم زمانی که تجزیه گر به تگ های آغازین یا پایانی میرسد چه تابعی اجرا شود.
  • تابع ()xml_set_character_data_handler را اضافه کرده ایم تا مشخص کنیم زمانی که تجزیه گر به character data میرسد چه تابعی اجرا شود.
  • سپس فایل note.xml را با ()xml_parse تجزیه کرده ایم.
  • از تابع ()xml_error_string نیز استفاده کرده ایم تا در صورت بروز خطا، خطا به صورت متنی برایمان نمایش داده شود.
  • در آخر تابع ()xml_parser_free را صدا کرده ایم تا مموری اشغال شده توسط ()xml_parser_create را آزاد کند.

تجزیه گر DOM

تجزیه گر DOM یک تجزیه گر درختی است. به تکه کد XML زیر نگاه کنید:

<?xml version="1.0" encoding="UTF-8"?>
<from>Jani</from>

DOM کد بالا را به این شکل می بیند:

  • سطح 1: سند XML
  • سطح 2: عنصر ریشه (root) که همان <from> است
  • سطح 3: عنصر متنی: "Jani"

نکته: هر دو تجزیه گر Expat و DOM جزء خود PHP هستند بنابراین برای استفاده از آن ها نیازی به هیچ کد خارجی ندارید.

برای کار با کد و مثال ها از همان فایل note.xml استفاده خواهیم کرد. مثلا می خواهیم تجزیه گر را راه اندازی کرده، XML را بارگذاری کنیم و خروجی اش را بگیریم:

<?php
$xmlDoc = new DOMDocument();
$xmlDoc->load("note.xml");

print $xmlDoc->saveXML();
?>

خروجی کد بالا عبارت زیر خواهد بود:

Tove Jani Reminder Don't forget me this weekend!

همچنین اگر از مرورگر خود با کلیک راست یا کلیدهای Ctrl + U گزینه ی View source را بزنید، ساختار HTML را به این شکل می بینید:

<?xml version="1.0" encoding="UTF-8"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

در واقع مثال بالا یک شیء DOMDocument ساخته و محتوای XML را از فایل note.xml وارد آن می کند. سپس تابع ()saveXML محتوای internal XML را در یک رشته قرار داده تا بتوانیم آن را نمایش دهیم.

حالا فرض کنید می خواهیم بین تمام عناصر XML گردش کنیم. در چنین حالتی می گوییم:

<?php
$xmlDoc = new DOMDocument();
$xmlDoc->load("note.xml");

$x = $xmlDoc->documentElement;
foreach ($x->childNodes AS $item) {
  print $item->nodeName . " = " . $item->nodeValue . "<br>";
}
?>

خروجی کد بالا به این شکل خواهد بود:

#text =
to = Tove
#text =
from = Jani
#text =
heading = Reminder
#text =
body = Don't forget me this weekend!
#text =

همانطور که در خروجی می بینید بین هر عنصر یک text node خالی وجود دارد؛ زمانی که XML ساخته می شود معمولا بین node هایش فضای خالی وجود دارد. از طرفی تجزیه گر DOM آن ها را به عنوان یک عنصر عادی می بیند و اگر حواستان به آن ها نباشد باعث بروز مشکل در برنامه تان می شوند.

XML و جاوا اسکریپت

بهتر است در پایان این مقاله نکته ای را مجددا بیان کنیم: کار با XML فقط وظیفه ی PHP نیست بلکه PHP یکی از راه های کار با XML است و این نیاز شما است که ابزار شما را انتخاب می کند. بیایید یک مثال را بررسی کنیم. در مثال زیر یک رشته را به یک شیء XML DOM تجزیه می کنیم و سپس با استفاده از جاوا اسکریپت اطلاعات داخل آن را بیرون می کشیم:

<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
var parser, xmlDoc;
var text = "<bookstore><book>" +
"<title>Everyday Italian</title>" +
"<author>Giada De Laurentiis</author>" +
"<year>2005</year>" +
"</book></bookstore>";

parser = new DOMParser();
xmlDoc = parser.parseFromString(text,"text/xml");

document.getElementById("demo").innerHTML =
xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue;
</script>

</body>
</html>

مشاهده ی خروجی

توضیح مثال:

ابتدا یک رشته را تعریف کرده ایم:

text = "<bookstore><book>" +
"<title>Everyday Italian</title>" +
"<author>Giada De Laurentiis</author>" +
"<year>2005</year>" +
"</book></bookstore>";

سپس یک شیء تجزیه گر DOM ساخته می شود:

parser = new DOMParser();

حالا تجزیه گر با استفاده از رشته ی متنی یک شیء جدید ایجاد می کند:

xmlDoc = parser.parseFromString(text,"text/xml");

البته مرورگرهای قدیمی (IE8 و نسخه های قبل تر) از شیء DOMParser پشتیبانی نمی کنند بنابراین باید به این روش آن ها را انجام دهیم:

<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
var parser, xmlDoc;
var text = "<bookstore><book>" +
"<title>Everyday Italian</title>" +
"<author>Giada De Laurentiis</author>" +
"<year>2005</year>" +
"</book></bookstore>";

if (window.DOMParser) {
  parser = new DOMParser();
  xmlDoc = parser.parseFromString(text,"text/xml");
} else {
  xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
  xmlDoc.async = false;
  xmlDoc.loadXML(text); 
} 

document.getElementById("demo").innerHTML =
xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue;
</script>

</body>
</html>

مشاهده ی خروجی

امیدوارم از این مقاله لذت برده باشید.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش PHP 7 توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.