XML Wrangler هي مكتبة PHP مبسطة مصممة لجعل القراءة وكتابة XML سهلة. تم بناء XML Wrangler مع وضع تجربة مطور في الاعتبار - يمكنك قراءة أي نوع من ملفات XML ، حتى مع مساحات الأسماء المعقدة وحتى ملفات XML الكبيرة. سوف يرمي أيضًا استثناءات إذا كان XML غير صالح!
يتم تثبيت XML Wrangler عبر الملحن.
composer require saloonphp/xml-wrangler
يتطلب PHP 8.1+
يمكن إجراء قراءة XML عن طريق تمرير سلسلة XML أو الملف في قارئ XML واستخدام إحدى الطرق العديدة للبحث وإيجاد عنصر أو قيمة محددة. يمكنك أيضًا تحويل كل عنصر إلى صفيف يمكن اجتيازه بسهولة إذا كنت تفضل ذلك. إذا كنت بحاجة إلى الوصول إلى سمات على عنصر ، فيمكنك استخدام Element
DTO وهو فئة بسيطة للوصول إلى المحتوى والسمات. يوفر XML Wrangler طرقًا للتكرار من خلال عناصر متعددة مع الحفاظ على عنصر واحد فقط في الذاكرة في وقت واحد.
< breakfast_menu >
< food soldOut = " false " bestSeller = " true " >
< name >Belgian Waffles</ name >
< price >$5.95</ price >
< description >Two of our famous Belgian Waffles with plenty of real maple syrup</ description >
< calories >650</ calories >
</ food >
< food soldOut = " false " bestSeller = " false " >
< name >Strawberry Belgian Waffles</ name >
< price >$7.95</ price >
< description >Light Belgian waffles covered with strawberries and whipped cream</ description >
< calories >900</ calories >
</ food >
< food soldOut = " false " bestSeller = " true " >
< name >Berry-Berry Belgian Waffles</ name >
< price >$8.95</ price >
< description >Light Belgian waffles covered with an assortment of fresh berries and whipped cream</ description >
< calories >900</ calories >
</ food >
</ breakfast_menu >
<?php
use Saloon XmlWrangler XmlReader ;
$ reader = XmlReader :: fromString ( $ xml );
// Retrieve all values as one simple array
$ reader -> values (); // ['breakfast_menu' => [['name' => '...'], ['name' => '...'], ['name' => '...']]
// Use dot-notation to find a specific element
$ reader -> value ( ' food.0 ' )-> sole (); // ['name' => 'Belgian Waffles', 'price' => '$5.95', ...]
// Use the element method to get a simple Element DTO containing attributes and content
$ reader -> element ( ' food.0 ' )-> sole (); // Element::class
// Use XPath to query the XML
$ reader -> xpathValue ( ' //food[@bestSeller="true"]/name ' )-> get (); // ['Belgian Waffles', 'Berry-Berry Belgian Waffles']
// Use getAttributes() to get the attributes on the elements
$ reader -> element ( ' food.0 ' )-> sole ()-> getAttributes (); // ['soldOut' => false, 'bestSeller' => true]
// Use getContent() to get the contents of the elements
$ reader -> element ( ' food.0 ' )-> sole ()-> getContent (); // ['name' => 'Belgian Waffles', 'price' => '$5.95', ...]
تعد كتابة XML بسيطة مثل تحديد مجموعة PHP واستخدام المفاتيح والقيم لتحديد العناصر. عندما تحتاج إلى تحديد عناصر ذات خصائص أخرى مثل السمات أو مساحات الأسماء ، يمكنك استخدام Element
DTO لتحديد عناصر أكثر تقدمًا.
<?php
use Saloon XmlWrangler Data Element ;
use Saloon XmlWrangler XmlWriter ;
$ writer = new XmlWriter ;
$ xml = $ writer -> write ( ' breakfast_menu ' , [
' food ' => [
[
' name ' => ' Belgian Waffles ' ,
' price ' => ' $5.95 ' ,
' description ' => ' Two of our famous Belgian Waffles with plenty of real maple syrup ' ,
' calories ' => ' 650 ' ,
],
[
' name ' => ' Strawberry Belgian Waffles ' ,
' price ' => ' $7.95 ' ,
' description ' => ' Light Belgian waffles covered with strawberries and whipped cream ' ,
' calories ' => ' 900 ' ,
],
// You can also use the Element class if you need to define elements with
// namespaces or with attributes.
Element :: make ([
' name ' => ' Berry-Berry Belgian Waffles ' ,
' price ' => ' $8.95 ' ,
' description ' => ' Light Belgian waffles covered with an assortment of fresh berries and whipped cream ' ,
' calories ' => ' 900 ' ,
])-> setAttributes ([ ' bestSeller ' => ' true ' ]),
],
]);
الرمز أعلاه سيقوم بإنشاء XML التالي
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< breakfast_menu >
< food >
< name >Belgian Waffles</ name >
< price >$5.95</ price >
< description >Two of our famous Belgian Waffles with plenty of real maple syrup</ description >
< calories >650</ calories >
</ food >
< food >
< name >Strawberry Belgian Waffles</ name >
< price >$7.95</ price >
< description >Light Belgian waffles covered with strawberries and whipped cream</ description >
< calories >900</ calories >
</ food >
< food bestSeller = " true " >
< name >Berry-Berry Belgian Waffles</ name >
< price >$8.95</ price >
< description >Light Belgian waffles covered with an assortment of fresh berries and whipped cream</ description >
< calories >900</ calories >
</ food >
</ breakfast_menu >
هذا القسم على الوثائق هو استخدام قارئ XML.
يمكن لقارئ XML قبول مجموعة متنوعة من أنواع الإدخال. يمكنك استخدام سلسلة أو ملف XML أو توفير مورد. يمكنك أيضًا قراءة XML مباشرة من استجابة PSR (مثل من Guzzle) أو استجابة الصالون.
use Saloon XmlWrangler XmlReader ;
$ reader = XmlReader :: fromString ( ' <?xml version="1.0" encoding="utf-8"?><breakfast_menu>... ' );
$ reader = XmlReader :: fromFile ( ' path/to/file.xml ' );
$ reader = XmlReader :: fromStream ( fopen ( ' path/to/file.xml ' , ' rb ' );
$ reader = XmlReader :: fromPsrResponse ( $ response );
$ reader = XmlReader :: fromSaloonResponse ( $ response );
التحذير بسبب قيود فئة PHP XMLReader الأساسية ، ستنشئ
fromStream
fromPsrResponse
وfromSaloon
ملفًا مؤقتًا على جهازك/خادمك للقراءة والتي سيتم إزالتها تلقائيًا عند تدمير القارئ. ستحتاج إلى التأكد من أن لديك مساحة تخزين كافية على جهازك لاستخدام هذه الطريقة.
يمكنك استخدام أساليب elements
values
لتحويل مستند XML بالكامل إلى صفيف. إذا كنت ترغب في الحصول على مجموعة من القيم ، فاستخدم طريقة values
- ولكن إذا كنت بحاجة إلى الوصول إلى السمات على العناصر ، فستقوم طريقة elements
بإرجاع مجموعة من DTOs Element
.
$ reader = XmlReader :: fromString (...);
$ elements = $ reader -> elements (); // Array of `Element::class` DTOs
$ values = $ reader -> values (); // Array of values.
ملاحظة إذا كنت تقرأ ملف XML كبير ، فيجب عليك استخدام أساليب
element
أوvalue
بدلاً من ذلك. يمكن أن تتكرر هذه الطرق من خلال ملفات XML الكبيرة دون نفاد الذاكرة.
يمكنك استخدام طريقة value
للحصول على قيمة عنصر معين. يمكنك استخدام Dot-Notation للبحث عن عناصر الأطفال. يمكنك أيضًا استخدام أعداد كاملة للعثور على مواقع محددة من عناصر متعددة. تبحث هذه الطريقة من خلال الجسم XML بأكمله بطريقة فعالة للذاكرة.
ستعيد هذه الطريقة فئة LazyQuery
التي لديها طرق مختلفة لاسترداد البيانات.
$ reader = XmlReader :: fromString ( '
<?xml version="1.0" encoding="utf-8"?>
<person>
<name>Sammyjo20</name>
<favourite-songs>
<song>Luke Combs - When It Rains It Pours</song>
<song>Sam Ryder - SPACE MAN</song>
<song>London Symfony Orchestra - Starfield Suite</song>
</favourite-songs>
</person>
' );
$ reader -> value ( ' person.name ' )-> sole () // ' Sammyjo20 '
$ reader -> value ( ' song ' )-> get (); // ['Luke Combs - When It Rains It Pours', 'Sam Ryder - SPACE MAN', ...]
$ reader -> value ( ' song.2 ' )-> sole (); // 'London Symfony Orchestra - Starfield Suite'
يمكنك استخدام طريقة element
للبحث عن عنصر معين. ستوفر هذه الطريقة فئة Element
تحتوي على القيمة والسمات. يمكنك استخدام Dot-Notation للبحث عن عناصر الأطفال. يمكنك أيضًا استخدام أعداد كاملة للعثور على مواقع محددة من عناصر متعددة. تبحث هذه الطريقة من خلال الجسم XML بأكمله بطريقة فعالة للذاكرة.
ستعيد هذه الطريقة فئة LazyQuery
التي لديها طرق مختلفة لاسترداد البيانات.
$ reader = XmlReader :: fromString ( '
<?xml version="1.0" encoding="utf-8"?>
<person>
<name>Sammyjo20</name>
<favourite-songs>
<song>Luke Combs - When It Rains It Pours</song>
<song>Sam Ryder - SPACE MAN</song>
<song>London Symfony Orchestra - Starfield Suite</song>
</favourite-songs>
</person>
' );
$ reader -> element ( ' name ' )-> sole (); // Element('Sammyjo20')
$ reader -> element ( ' song ' )-> get (); // [Element('Luke Combs - When It Rains It Pours'), Element('Sam Ryder - SPACE MAN'), ...]
$ reader -> element ( ' song.2 ' )-> sole (); // Element('London Symfony Orchestra - Starfield Suite')
في بعض الأحيان يكون من الأسهل اجتياز مستند XML عندما لا داعي للقلق بشأن مساحات الأسماء والبادئات للعناصر. إذا كنت ترغب في إزالتها ، فيمكنك استخدام طريقة removeNamespaces()
على القارئ.
$ reader = XmlReader :: fromString (...);
$ reader -> removeNamespaces ();
عند البحث في ملف كبير ، يمكنك استخدام أساليب lazy
أو collectLazy
التي ستعيد مولدًا للنتائج التي تحافظ على عنصر واحد فقط في الذاكرة في وقت واحد.
$ names = $ reader -> element ( ' name ' )-> lazy ();
foreach ( $ names as $ name ) {
//
}
إذا كنت تستخدم Laravel ، فيمكنك استخدام أساليب collect
و collectLazy
التي ستحول العناصر إلى مجموعة Laravel/Lazy. إذا كنت لا تستخدم Laravel ، فيمكنك تثبيت حزمة illuminate/collections
عبر الملحن لإضافة هذه الوظيفة.
$ names = $ reader -> value ( ' name ' )-> collect ();
$ names = $ reader -> value ( ' name ' )-> collectLazy ();
في بعض الأحيان قد ترغب في البحث عن عنصر أو قيمة محددة حيث يحتوي العنصر على سمة محددة. يمكنك القيام بذلك عن طريق توفير وسيطة ثانية إلى طريقة value
أو element
. سيؤدي هذا إلى البحث عن العنصر الأخير للسمات وسيعود إذا كانت متطابقة.
$ reader = XmlReader :: fromString ( '
<?xml version="1.0" encoding="utf-8"?>
<person>
<name>Sammyjo20</name>
<favourite-songs>
<song>Luke Combs - When It Rains It Pours</song>
<song>Sam Ryder - SPACE MAN</song>
<song recent="true">London Symfony Orchestra - Starfield Suite</song>
</favourite-songs>
</person>
' );
$ reader -> element ( ' song ' , [ ' recent ' => ' true ' ])-> sole (); // Element('London Symfony Orchestra - Starfield Suite')
$ reader -> value ( ' song ' , [ ' recent ' => ' true ' ])-> sole (); // 'London Symfony Orchestra - Starfield Suite'
XPath هي وسيلة رائعة للبحث من خلال XML. مع سلسلة واحدة ، يمكنك البحث عن عنصر معين ، مع سمات أو فهارس محددة. إذا كنت مهتمًا بتعلم XPath ، فيمكنك النقر هنا للحصول على ملاءمة غش مفيدة.
يمكنك استخدام طريقة xpathValue
للعثور على قيمة عنصر معين مع استعلام XPath. ستعود هذه الطريقة إلى فئة Query
لها طرق مختلفة لاسترداد البيانات.
<?php
$ reader = XmlReader :: fromString (...);
$ reader -> xpathValue ( ' //person/favourite-songs/song[3] ' )-> sole (); // 'London Symfony Orchestra - Starfield Suite'
يمكنك استخدام طريقة xpathElement
للعثور على عنصر معين مع استعلام XPath. ستعود هذه الطريقة إلى فئة Query
لها طرق مختلفة لاسترداد البيانات.
<?php
$ reader = XmlReader :: fromString (...);
$ reader -> xpathElement ( ' //person/favourite-songs/song[3] ' )-> sole (); // Element('London Symfony Orchestra - Starfield Suite')
تحذير بسبب القيود مع XPath - الأساليب المذكورة أعلاه المستخدمة للاستعلام مع XPath ليست آمنة للذاكرة وقد لا تكون مناسبة لمستندات XML الكبيرة.
قد تجد نفسك مع وثيقة XML التي تحتوي على سمة xmlns
غير المترجمة - مثل هذا:
< container xmlns = " http://example.com/xml-wrangler/person " xmlns : xsi = " http://www.w3.org/2001/XMLSchema-instance " />
عندما يحدث هذا ، ستقوم XML Wrangler بإزالة مساحات الأسماء غير المقيدة تلقائيًا لتحسين التوافق. إذا كنت ترغب في الاحتفاظ بمساحات الأسماء هذه ، فيمكنك استخدام setXpathNamespaceMap
لخريطة كل مساحة اسم XML غير المُعدة.
$ reader = XmlReader :: fromString (...);
$ reader -> setXpathNamespaceMap ([
' root ' => ' http://example.com/xml-wrangler/person ' ,
]);
$ reader -> xpathValue ( ' //root:person/root:favourite-songs/root:song[3] ' )-> sole ();
هذا القسم على الوثائق هو لاستخدام كاتب XML.
الاستخدام الأساسي للقارئ هو استخدام مفاتيح السلسلة لأسماء العناصر والقيم لقيم العنصر. يقبل الكاتب صفائف متداخلة بلا حدود للعناصر المتداخلة.
use Saloon XmlWrangler XmlWriter ;
$ xml = XmlWriter :: make ()-> write ( ' root ' , [
' name ' => ' Sam ' ,
' twitter ' => ' @carre_sam ' ,
' facts ' => [
' favourite-song ' => ' Luke Combs - When It Rains It Pours '
],
]);
سيتم تحويل الرمز أعلاه إلى XML التالي
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< root >
< name >Sam</ name >
< twitter >@carre_sam</ twitter >
< facts >
< favourite-song >Luke Combs - When It Rains It Pours</ favourite-song >
</ facts >
</ root >
عند كتابة XML ، ستحتاج غالبًا إلى تحديد السمات ومساحات الأسماء على عناصرك. يمكنك استخدام فئة Element
في صفيف XML لإضافة عنصر مع سمة أو مساحة اسم. يمكنك مزج فئة Element
مع المصفوفات الأخرى وقيم السلسلة.
use Saloon XmlWrangler XmlWriter ;
use Saloon XmlWrangler Data Element ;
$ xml = XmlWriter :: make ()-> write ( ' root ' , [
' name ' => ' Sam ' ,
' twitter ' => Element :: make ( ' @carre_sam ' )-> addAttribute ( ' url ' , ' https://twitter.com/@carre_sam ' ),
' facts ' => [
' favourite-song ' => ' Luke Combs - When It Rains It Pours '
],
' soap:custom-namespace ' => Element :: make ()-> addNamespace ( ' soap ' , ' http://www.w3.org/2003/05/soap-envelope ' ),
]);
سيؤدي هذا إلى XML التالي
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< root >
< name >Sam</ name >
< twitter url = " https://twitter.com/@carre_sam " >@carre_sam</ twitter >
< facts >
< favourite-song >Luke Combs - When It Rains It Pours</ favourite-song >
</ facts >
< soap : custom-namespace xmlns : soap = " http://www.w3.org/2003/05/soap-envelope " />
</ root >
ستحتاج غالبًا إلى تحديد مجموعة من العناصر. يمكنك القيام بذلك ببساطة عن طريق توفير مجموعة من القيم أو فئات العناصر.
use Saloon XmlWrangler XmlWriter ;
use Saloon XmlWrangler Data Element ;
$ xml = XmlWriter :: make ()-> write ( ' root ' , [
' name ' => ' Luke Combs ' ,
' songs ' => [
' song ' => [
' Fast Car ' ,
' The Kind Of Love We Make ' ,
' Beautiful Crazy ' ,
Element :: make ( ' She Got The Best Of Me ' )-> addAttribute ( ' hit ' , ' true ' ),
],
],
]);
سيؤدي هذا إلى XML التالي
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< root >
< name >Luke Combs</ name >
< songs >
< song >Fast Car</ song >
< song >The Kind Of Love We Make</ song >
< song >Beautiful Crazy</ song >
< song hit = " true " >She Got The Best Of Me</ song >
</ songs >
</ root >
في بعض الأحيان قد تحتاج إلى تغيير اسم عنصر الجذر. يمكن تخصيص هذا كوسيطة أول طريقة write
.
$ xml = XmlWriter :: make ()-> write ( ' custom-root ' , [...])
إذا كنت ترغب في إضافة سمات ومساحات أسماء إلى عنصر الجذر ، يمكنك استخدام فئة RootElement
هنا أيضًا.
use Saloon XmlWrangler Data RootElement ;
$ rootElement = RootElement :: make ( ' root ' )-> addNamespace ( ' soap ' , ' http://www.w3.org/2003/05/soap-envelope ' );
$ xml = XmlWriter :: make ()-> write ( $ rootElement , [...])
إذا كنت بحاجة إلى إضافة علامة CDATA ، يمكنك استخدام فئة CDATA
.
use Saloon XmlWrangler Data CDATA ; use Saloon XmlWrangler XmlWriter ;
use Saloon XmlWrangler Data Element ;
$ xml = XmlWriter :: make ()-> write ( ' root ' , [
' name ' => ' Sam ' ,
' custom ' => CDATA :: make ( ' Here is some CDATA content! ' ),
]);
سيؤدي هذا إلى XML التالي
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< root >
< name >Sam</ name >
< custom > <![CDATA[ Here is some CDATA content! ]]> </ custom >
</ root >
في بعض الأحيان ، قد يكون لديك جزء من XML الذي ستعيد استخدامه عبر طلبات XML متعددة في التطبيق الخاص بك. باستخدام XML Wrangler ، يمكنك إنشاء عناصر "قابلة للتكوين" حيث يمكنك تحديد محتوى XML الخاص بك في فصل يمكنك إعادة استخدامه عبر التطبيق الخاص بك. تمديد فئة Element
واستخدم طريقة compose
ثابت محمية.
<?php
use Saloon XmlWrangler XmlWriter ;
use Saloon XmlWrangler Data Element ;
class BelgianWafflesElement extends Element
{
protected function compose (): void
{
$ this
-> setAttributes ([
' soldOut ' => ' false ' ,
' bestSeller ' => ' true ' ,
])
-> setContent ([
' name ' => ' Belgian Waffles ' ,
' price ' => ' $5.95 ' ,
' description ' => ' Two of our famous Belgian Waffles with plenty of real maple syrup ' ,
' calories ' => ' 650 ' ,
]);
}
}
$ writer = XmlWriter :: make ()-> write ( ' root ' , [
' food ' => new BelgianWafflesElement ,
]);
سيؤدي هذا إلى XML مثل هذا:
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< breakfast_menu >
< food soldOut = " false " bestSeller = " true " >
< name >Belgian Waffles</ name >
< price >$5.95</ price >
< description >Two of our famous Belgian Waffles with plenty of real maple syrup</ description >
< calories >650</ calories >
</ food >
</ breakfast_menu >
إن ترميز XML الافتراضي هو utf-8
، والنسخة الافتراضية من XML هي 1.0
، والوقوف الافتراضي null
(تحلات XML لا تفسر أي سمة مستقلة مثل false
). إذا كنت ترغب في تخصيص هذا ، فيمكنك مع أساليب setXmlEncoding
و setXmlVersion
و setXmlStandalone
على الكاتب.
use Saloon XmlWrangler XmlWriter ;
$ writer = new XmlWriter ();
$ writer -> setXmlEncoding ( ' ISO-8859-1 ' );
$ writer -> setXmlVersion ( ' 2.0 ' );
$ writer -> setXmlStandalone ( true );
// $writer->write(...);
ما الذي ينتج عن إعلان XML <?xml version="2.0" encoding="ISO-8859-1" standalone="yes"?>
يمكنك إضافة "تعليمات معالجة" مخصصة إلى XML باستخدام طريقة addProcessingInstruction
.
use Saloon XmlWrangler XmlWriter ;
$ writer = new XmlWriter ();
$ writer -> addProcessingInstruction ( ' xml-stylesheet ' , ' type="text/xsl" href="base.xsl" ' );
$ xml = $ writer -> write ( ' root ' , [ ' name ' => ' Sam ' ]);
سيؤدي هذا إلى XML التالي
<? xml version = " 1.0 " encoding = " utf-8 " ?>
<? xml-stylesheet type = " text/xsl " href = " base.xsl " ?>
< root >
< name >Sam</ name >
</ root >
بشكل افتراضي ، لم يتم تحديد XML المكتوب. يمكنك توفير الوسيطة الثالثة لطريقة write
لتحسين XML.
use Saloon XmlWrangler XmlWriter ;
$ xml = XmlWriter :: make ()-> write ( ' root ' , [...], minified: true );
XML Wrangler عبارة عن غلاف بسيط حول مكتبتين قويتين حقًا تقومان بالكثير من العمل. كل من المكتبات رائعة وتستحق نجمة!