هناك العديد من التقنيات لقراءة وكتابة XML باستخدام PHP. توفر هذه المقالة ثلاث طرق لقراءة XML: استخدام مكتبة DOM، واستخدام محلل SAX، واستخدام التعبيرات العادية. يتم أيضًا تناول كتابة XML باستخدام قوالب نص DOM وPHP.
قراءة وكتابة لغة التوصيف القابلة للتوسيع (XML) في PHP قد تبدو مخيفة بعض الشيء. في الواقع، XML وجميع التقنيات المرتبطة به يمكن أن تكون مخيفة، ولكن قراءة وكتابة XML في PHP لا يجب أن تكون مهمة مخيفة. أولاً، عليك أن تتعلم القليل عن لغة XML، ما هي وماذا يمكنك أن تفعل بها. بعد ذلك، عليك أن تتعلم كيفية قراءة وكتابة XML في PHP، وهناك طرق عديدة للقيام بذلك.
توفر هذه المقالة مقدمة مختصرة عن لغة XML ثم تشرح كيفية قراءة وكتابة لغة XML باستخدام لغة PHP.
ما هو XML؟
XML هو تنسيق لتخزين البيانات. ولا يحدد البيانات التي يتم حفظها، ولا يحدد تنسيق البيانات. يقوم XML ببساطة بتعريف العلامات وسمات تلك العلامات. تبدو علامات XML جيدة التنسيق كما يلي:
<الاسم>جاك هيرينجتون</الاسم>
تحتوي علامة <name> هذه على بعض النص: Jack Herrington.
يبدو ترميز XML بدون نص كما يلي:
<PowerUp/>
هناك أكثر من طريقة لكتابة شيء ما في XML. على سبيل المثال، تشكل هذه العلامة نفس مخرجات العلامة السابقة:
<باور اب></باور اب>
يمكنك أيضًا إضافة سمات إلى علامات XML. على سبيل المثال، تحتوي علامة <name> هذه على السمتين الأولى والأخيرة:
<الاسم الأول = "جاك" الأخير = "هيرنجتون" />
يمكن أيضًا ترميز الأحرف الخاصة بتنسيق XML. على سبيل المثال، يمكن ترميز الرمز & على النحو التالي:
&
يكون ملف XML الذي يحتوي على علامات وسمات منسقًا بشكل جيد إذا تم تنسيقه مثل المثال، مما يعني أن العلامات متماثلة وأن الأحرف مشفرة بشكل صحيح. تعتبر القائمة 1 مثالاً على XML جيدة التصميم.
القائمة 1. مثال على قائمة كتب XML
<كتب>
<كتاب>
<المؤلف>جاك هيرينجتون</المؤلف>
<العنوان> PHP Hacks>/العنوان>
<الناشر>أورايلي</الناشر>
</كتاب>
<كتاب>
<المؤلف>جاك هيرينجتون</المؤلف>
<العنوان>البودكاست المأجورون</العنوان>
<الناشر>أورايلي</الناشر>
</كتاب>
</كتب>
|
يحتوي ملف XML الموجود في القائمة 1 على قائمة بالكتب. تحتوي العلامة <books> الأصلية على مجموعة من علامات <book>، تحتوي كل منها على علامات <author> و<title> و<publisher>.
يكون مستند XML صحيحًا عندما يتم التحقق من بنية الترميز ومحتواه بواسطة ملف مخطط خارجي. يمكن تحديد ملفات المخطط بتنسيقات مختلفة. في هذه المقالة، كل ما تحتاجه هو XML جيد التصميم.
إذا كنت تعتقد أن XML يشبه إلى حد كبير لغة توصيف النص التشعبي (HTML)، فأنت على حق. XML وHTML هما لغتان مبنيتان على الترميز ولهما العديد من أوجه التشابه. ومع ذلك، من المهم الإشارة إلى أنه على الرغم من أن مستند XML قد يكون بتنسيق HTML جيدًا، إلا أنه ليست كل مستندات HTML عبارة عن XML جيد التكوين. تعتبر علامة السطر الجديد (br) مثالاً جيدًا للفرق بين XML وHTML. علامة السطر الجديد هذه عبارة عن HTML منسق بشكل جيد، ولكنها ليست XML جيدة التصميم:
<p>هذه فقرة<br>
مع فاصل الأسطر </p>
علامة السطر الجديد هذه عبارة عن XML وHTML جيدة التنسيق:
<p>هذه فقرة<br />
مع فاصل الأسطر </p>
إذا كنت تريد كتابة HTML بتنسيق XML جيد التصميم، فاتبع معيار لغة توصيف النص التشعبي القابل للتوسيع (XHTML) الخاص بلجنة W3C (راجع الموارد ). يمكن لجميع المتصفحات الحديثة تقديم XHTML. علاوة على ذلك، يمكنك استخدام أدوات XML لقراءة XHTML والعثور على البيانات في المستند، وهو أمر أسهل بكثير من تحليل HTML.
قراءة XML باستخدام مكتبة DOM
أسهل طريقة لقراءة ملفات XML جيدة التكوين هي استخدام مكتبة Document Object Model (DOM) المجمعة في بعض عمليات تثبيت PHP. تقوم مكتبة DOM بقراءة مستند XML بأكمله في الذاكرة وتمثيله كشجرة عقدة، كما هو موضح في الشكل 1.
الشكل 1. شجرة XML DOM للكتاب XML
تحتوي عقدة الكتب الموجودة أعلى الشجرة على علامتين تابعتين للكتاب. يوجد في كل كتاب عدة نقاط: المؤلف والناشر والعنوان. تحتوي كل من عقد المؤلف والناشر والعنوان على عقد فرعية نصية تحتوي على نص.
يظهر الكود الذي يقرأ ملف XML للكتاب ويعرض المحتوى باستخدام DOM في القائمة 2.
القائمة 2. قراءة كتاب XML باستخدام DOM
<?php
$doc = new DOMDocument();
$doc->load( 'books.xml' );
$books = $doc->getElementsByTagName( "book" );
foreach (كتب $ ككتاب $)
{
$authors = $book->getElementsByTagName( "author" );
$author = $authors->item(0)->nodeValue;
$publishers = $book->getElementsByTagName( "publisher");
$publisher = $publishers->item(0)->nodeValue;
$titles = $book->getElementsByTagName( "title" );
$title = $titles->item(0)->nodeValue;
صدى "$title - $author - $publishern";
}
?>
|
يقوم البرنامج النصي أولاً بإنشاء كائن DOMdocument جديد ويقوم بتحميل كتاب XML إلى هذا الكائن باستخدام طريقة التحميل. بعد ذلك، يستخدم البرنامج النصي طريقة getElementsByName للحصول على قائمة بجميع العناصر تحت الاسم المحدد.
في حلقة عقدة الكتاب، يستخدم البرنامج النصي طريقة getElementsByName للحصول على قيمة العقدة لعلامات المؤلف والناشر والعنوان. قيمة العقدة هي النص الموجود في العقدة. ثم يعرض البرنامج النصي هذه القيم.
يمكنك تشغيل البرامج النصية PHP على سطر الأوامر مثل هذا:
%phpe1.php
PHP Hacks - جاك هيرينجتون - أورايلي
حيل البث الصوتي – جاك هيرينجتون – أورايلي
%
كما ترون، كل كتلة كتاب تنتج سطرًا واحدًا. هذه بداية جيدة. ولكن ماذا لو لم يكن لديك حق الوصول إلى مكتبة XML DOM؟
قراءة XML مع محلل SAX
هناك طريقة أخرى لقراءة XML وهي استخدام محلل XML Simple API (SAX). تشتمل معظم عمليات تثبيت PHP على محلل SAX. يعمل المحلل اللغوي SAX على نموذج رد الاتصال. في كل مرة يتم فيها فتح علامة أو إغلاقها، أو في كل مرة يرى المحلل اللغوي نصًا، يتم استدعاء الوظيفة المعرفة من قبل المستخدم مرة أخرى بمعلومات حول العقدة أو النص.
ميزة محلل SAX هي أنه خفيف الوزن حقًا. لا يحتفظ المحلل اللغوي بالمحتوى في الذاكرة لفترات طويلة من الزمن، لذلك يمكن استخدامه للملفات الكبيرة جدًا. العيب هو أن كتابة ردود الاتصال المحلل اللغوي SAX مرهقة للغاية. تعرض القائمة 3 الكود الذي يستخدم SAX لقراءة ملف XML للكتاب وعرض المحتوى.
القائمة 3. قراءة كتاب XML باستخدام محلل SAX
<?php
$g_books = array();
$g_elem = null;
وظيفة startElement( $parser, $name, $attrs )
{
كتب g_book العالمية، $g_elem؛
إذا ( $name == 'BOOK') $g_books []= array();
$g_elem = $name;
}
وظيفة endElement( $محلل، $name )
{
عالمي $g_elem;
$g_elem = null;
}
وظيفة textData( $محلل، $text )
{
كتب g_book العالمية، $g_elem؛
إذا ($g_elem == 'المؤلف' ||
$g_elem == 'الناشر' ||
$g_elem == 'العنوان' )
{
$g_books[ العد( $g_books ) - 1][ $g_elem ] = $text;
}
}
$parser = xml_parser_create();
xml_set_element_handler( $parser, "startElement", "endElement" );
xml_set_character_data_handler( $parser, "textData" );
$f = fopen( 'books.xml', 'r' );
بينما( $data = fread( $f, 4096 ) )
{
xml_parse( $parser, $data );
}
xml_parser_free( $parser );
foreach($g_books كـ $book)
{
echo $book['TITLE']." - ".$book['AUTHOR']." - ";
echo $book['PUBLISHER']."n";
}
?>
|
يقوم البرنامج النصي أولاً بإعداد مصفوفة g_books، التي تحتوي على جميع الكتب ومعلومات الكتاب في الذاكرة، ويحتفظ المتغير g_elem باسم العلامة التي يعالجها البرنامج النصي حاليًا. ثم يحدد البرنامج النصي وظيفة رد الاتصال. في هذا المثال، وظائف رد الاتصال هي startElement وendElement وtextData. عند فتح العلامة وإغلاقها، قم باستدعاء الدالتين startElement وendElement على التوالي. يتم استدعاء TextData على النص الموجود بين علامتي الفتح والإغلاق.
في هذا المثال، تبحث علامة startElement عن علامة الكتاب لبدء عنصر جديد في مصفوفة الكتاب. تقوم وظيفة textData بعد ذلك بالبحث في العنصر الحالي لمعرفة ما إذا كان ناشرًا أو عنوانًا أو علامة مؤلف. إذا كان الأمر كذلك، فإن الوظيفة تضع النص الحالي في الكتاب الحالي.
للسماح بمواصلة التحليل، يقوم البرنامج النصي بإنشاء محلل باستخدام وظيفة xml_parser_create. ثم قم بتعيين مقبض رد الاتصال. بعد ذلك، يقرأ البرنامج النصي الملف ويرسل أجزاء من الملف إلى المحلل اللغوي. بعد قراءة الملف، تقوم الدالة xml_parser_free بإزالة المحلل اللغوي. تقوم نهاية البرنامج النصي بإخراج محتويات مصفوفة g_books.
كما ترون، هذا أصعب بكثير من كتابة نفس الوظيفة في DOM. ماذا لو لم تكن هناك مكتبة DOM ولا مكتبة SAX؟ هل هناك أي بدائل؟
تحليل XML مع التعبيرات العادية
أنا متأكد من أن بعض المهندسين سوف ينتقدونني لمجرد ذكر هذه الطريقة، ولكن من الممكن تحليل XML باستخدام التعبيرات العادية. تعرض القائمة 4 مثالاً لاستخدام الدالة preg_ لقراءة ملف كتاب.
القائمة 4. قراءة XML مع التعبيرات العادية
<?php
$xml = "";
$f = fopen( 'books.xml', 'r' );
while( $data = fread( $f, 4096 ) ) { $xml .= $data };
فكلوز($f);
preg_match_all( "/<book>(.*?)</book>/s"،
$xml، $bookblocks )؛
foreach( $bookblocks[1] كـ $block )
{
preg_match_all( "/<author>(.*?)</author>/"،
$block، $author )؛
preg_match_all( "/<title>(.*?)</title>/"،
كتلة $، عنوان $)؛
preg_match_all( "/<publisher>(.*?)</publisher>/"،
$block، $publisher )؛
echo( $title[1][0]." - ".$author[1][0]." - ".
$publisher[1][0]."n" );
}
?>
|
لاحظ مدى قصر هذا الرمز. في البداية، يقرأ الملف في سلسلة كبيرة. ثم استخدم وظيفة regex لقراءة كل عنصر في الكتاب. وأخيرًا، استخدم حلقة foreach للتنقل عبر كل كتلة كتاب واستخراج المؤلف والعنوان والناشر.
إذن أين العيوب؟ تكمن المشكلة في استخدام كود التعبير العادي لقراءة XML في أنه لا يتم التحقق أولاً للتأكد من أن XML منسق بشكل جيد. وهذا يعني أنه لا توجد طريقة لمعرفة ما إذا كان ملف XML قد تم تشكيله بشكل جيد قبل قراءته. كما أن بعض ملفات XML جيدة التكوين قد لا تتطابق مع التعبير العادي، لذا يجب تعديلها لاحقًا.
لا أوصي مطلقًا باستخدام التعبيرات العادية لقراءة XML، ولكنها في بعض الأحيان تكون أفضل طريقة للتوافق لأن وظائف التعبير العادي متاحة دائمًا. لا تستخدم التعبيرات العادية لقراءة XML مباشرة من المستخدم لأنه لا يمكنك التحكم في تنسيق XML أو بنيته. يجب عليك دائمًا استخدام مكتبة DOM أو محلل SAX لقراءة XML من المستخدم. كتابة XML باستخدام DOM
قراءة XML ليست سوى جزء من المعادلة. كيف تكتب XML؟ أفضل طريقة لكتابة XML هي استخدام DOM. توضح القائمة 5 كيفية إنشاء DOM لملف XML للكتاب.
القائمة 5. كتابة كتاب XML باستخدام DOM
<?php
كتب $ = مصفوفة () ؛
كتب $ [] = مصفوفة(
'title' => 'اختراقات PHP'،
"المؤلف" => "جاك هيرينجتون"،
'الناشر' => "أورايلي"
);
كتب $ [] = مصفوفة(
'title' => 'اختراقات البث الصوتي'،
"المؤلف" => "جاك هيرينجتون"،
'الناشر' => "أورايلي"
);
$doc = new DOMDocument();
$doc->formatOutput = true;
$r = $doc->createElement( "books");
$doc->appendChild( $r );
foreach (كتب $ ككتاب $)
{
$b = $doc->createElement( "book" );
$author = $doc->createElement( "author" );
$author->appendChild(
$doc->createTextNode( $book['author'] )
);
$b->appendChild( $author);
$title = $doc->createElement( "title" );
$عنوان->appendChild(
$doc->createTextNode( $book['title'] )
);
$b->appendChild( $title);
$publisher = $doc->createElement( "publisher" );
$publisher->appendChild(
$doc->createTextNode( $book['publisher'] )
);
$b->appendChild( $publisher);
$r->appendChild( $b );
}
صدى $doc->saveXML();
?>
|
في الجزء العلوي من البرنامج النصي، يتم تحميل مجموعة الكتب مع بعض نماذج الكتب. يمكن أن تأتي هذه البيانات من المستخدم أو من قاعدة البيانات.
بعد تحميل نماذج الكتب، يقوم البرنامج النصي بإنشاء DOMDocument جديد وإضافة عقدة الكتب الجذرية إليه. يقوم البرنامج النصي بعد ذلك بإنشاء عقد لكل مؤلف كتاب وعنوانه وناشره، ويضيف عقدًا نصية إلى كل عقدة. الخطوة الأخيرة لكل عقدة كتاب هي إعادة إضافتها إلى كتب العقدة الجذرية.
في نهاية البرنامج النصي، استخدم طريقة saveXML لإخراج XML إلى وحدة التحكم. (يمكنك أيضًا استخدام طريقة الحفظ لإنشاء ملف XML.) يتم عرض مخرجات البرنامج النصي في القائمة 6.
القائمة 6. إخراج البرنامج النصي لبناء DOM
%phpe4.php
<?xml الإصدار = "1.0"?>
<كتب>
<كتاب>
<المؤلف>جاك هيرينجتون</المؤلف>
<العنوان> PHP Hacks>/العنوان>
<الناشر>أورايلي</الناشر>
</كتاب>
<كتاب>
<المؤلف>جاك هيرينجتون</المؤلف>
<العنوان>البودكاست المأجورون</العنوان>
<الناشر>أورايلي</الناشر>
</كتاب>
</كتب>
%
|
القيمة الحقيقية لاستخدام DOM هي أن XML الذي ينشئه يكون دائمًا جيد التنسيق. ولكن ماذا لو لم تتمكن من إنشاء XML باستخدام DOM؟
كتابة XML في PHP
إذا لم يكن DOM متاحًا، فيمكن كتابة XML باستخدام قوالب نص PHP. توضح القائمة 7 كيفية إنشاء PHP لملف XML للكتاب.
قائمة 7. كتابة كتاب XML في PHP
<?php
كتب $ = مصفوفة () ؛
كتب $ [] = مصفوفة(
'title' => 'اختراقات PHP'،
"المؤلف" => "جاك هيرينجتون"،
'الناشر' => "أورايلي"
);
كتب $ [] = مصفوفة(
'title' => 'اختراقات البث الصوتي'،
"المؤلف" => "جاك هيرينجتون"،
'الناشر' => "أورايلي"
);
?>
<كتب>
<?php
foreach (كتب $ ككتاب $)
{
?>
<كتاب>
<title><?php echo( $book['title'] ?></title>
<author><?php echo( $book['author'] ?>
</المؤلف>
<publisher><?php echo( $book['publisher'] );
</الناشر>
</كتاب>
<?php
}
?>
</كتب>
|
الجزء العلوي من البرنامج النصي يشبه البرنامج النصي DOM. يفتح الجزء السفلي من البرنامج النصي علامة الكتب ثم يتكرر خلال كل كتاب، مما يؤدي إلى إنشاء علامة الكتاب وجميع علامات العنوان الداخلية والمؤلف والناشر.
المشكلة في هذا النهج هي ترميز الكيانات. للتأكد من تشفير الكيانات بشكل صحيح، يجب استدعاء وظيفة htmlentities على كل عنصر، كما هو موضح في القائمة 8.
القائمة 8. كيانات التشفير باستخدام وظيفة htmlentities
<كتب>
<?php
foreach (كتب $ ككتاب $)
{
$title = htmlentities( $book['title'], ENT_QUOTES );
$author = htmlentities( $book['author'], ENT_QUOTES );
$publisher = htmlentities( $book['publisher'], ENT_QUOTES );
?>
<كتاب>
<عنوان><?php echo( $title ?></title>
<author><?php echo( $author ?> </author>
<ناشر><?php echo( $publisher ?>
</الناشر>
</كتاب>
<?php
}
?>
</كتب>
|
هذا هو المكان الذي تصبح فيه كتابة XML في لغة PHP الأساسية أمرًا مزعجًا. تعتقد أنك قمت بإنشاء XML مثالي، ولكن بمجرد محاولة استخدام البيانات، تكتشف أن بعض العناصر تم ترميزها بشكل غير صحيح.
خاتمة
هناك دائمًا الكثير من المبالغة والارتباك المحيط بـ XML. ومع ذلك، فالأمر ليس بالصعوبة التي تظنها - خاصة في لغة رائعة مثل PHP. بمجرد فهم XML وتنفيذه بشكل صحيح، ستجد العديد من الأدوات القوية تحت تصرفك. XPath وXSLT هما أداتان تستحقان الدراسة.