XML Wrangler adalah perpustakaan PHP sederhana yang dirancang untuk membuat membaca dan menulis XML mudah. XML Wrangler telah dibangun dengan mempertimbangkan pengalaman pengembang - Anda dapat membaca semua jenis file XML, bahkan dengan ruang nama yang kompleks dan bahkan file XML besar. Ini juga akan melempar pengecualian jika XML tidak valid!
XML Wrangler diinstal melalui komposer.
composer require saloonphp/xml-wrangler
Membutuhkan PHP 8.1+
Membaca XML dapat dilakukan dengan meneruskan string XML atau file ke pembaca XML dan menggunakan salah satu dari banyak metode untuk mencari dan menemukan elemen atau nilai tertentu. Anda juga dapat mengubah setiap elemen menjadi array yang mudah dilalui jika Anda mau. Jika Anda perlu mengakses atribut pada elemen, Anda dapat menggunakan Element
DTO yang merupakan kelas sederhana untuk mengakses konten dan atribut. XML Wrangler menyediakan metode untuk beralih melalui beberapa elemen sambil hanya menjaga satu elemen dalam memori pada satu waktu.
< 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', ...]
Menulis XML sesederhana mendefinisikan array PHP dan menggunakan kunci dan nilai untuk mendefinisikan elemen. Ketika Anda perlu mendefinisikan elemen dengan beberapa karakteristik lagi seperti atribut atau ruang nama, Anda dapat menggunakan Element
DTO untuk mendefinisikan elemen yang lebih maju.
<?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 ' ]),
],
]);
Kode di atas akan membuat XML berikut
<? 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 >
Bagian ini pada dokumentasi ini adalah untuk menggunakan pembaca XML.
Pembaca XML dapat menerima berbagai jenis input. Anda dapat menggunakan string XML, file, atau menyediakan sumber daya. Anda juga dapat membaca XML langsung dari respons PSR (seperti dari Guzzle) atau respons saloon.
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 );
PERINGATAN Karena keterbatasan kelas PHP XMLREADER yang mendasarinya, metode
fromStream
,fromPsrResponse
danfromSaloon
akan membuat file sementara di mesin/server Anda untuk dibaca dari mana akan secara otomatis dihapus ketika pembaca dirusak. Anda perlu memastikan bahwa Anda memiliki penyimpanan yang cukup pada mesin Anda untuk menggunakan metode ini.
Anda dapat menggunakan metode elements
dan values
untuk mengubah seluruh dokumen XML menjadi array. Jika Anda ingin array nilai, gunakan metode values
- tetapi jika Anda perlu mengakses atribut pada elemen, metode elements
akan mengembalikan array Element
DTO.
$ reader = XmlReader :: fromString (...);
$ elements = $ reader -> elements (); // Array of `Element::class` DTOs
$ values = $ reader -> values (); // Array of values.
CATATAN Jika Anda membaca file XML besar, Anda harus menggunakan
element
atau metodevalue
sebagai gantinya. Metode ini dapat mengulangi file XML besar tanpa kehabisan memori.
Anda dapat menggunakan metode value
untuk mendapatkan nilai elemen tertentu. Anda dapat menggunakan notasi dot untuk mencari elemen anak. Anda juga dapat menggunakan seluruh bilangan bulat untuk menemukan posisi spesifik dari beberapa elemen. Metode ini mencari melalui seluruh badan XML dengan cara yang efisien memori.
Metode ini akan mengembalikan kelas LazyQuery
yang memiliki metode berbeda untuk mengambil data.
$ 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'
Anda dapat menggunakan metode element
untuk mencari elemen tertentu. Metode ini akan menyediakan kelas Element
yang berisi nilai dan atribut. Anda dapat menggunakan notasi dot untuk mencari elemen anak. Anda juga dapat menggunakan seluruh bilangan bulat untuk menemukan posisi spesifik dari beberapa elemen. Metode ini mencari melalui seluruh badan XML dengan cara yang efisien memori.
Metode ini akan mengembalikan kelas LazyQuery
yang memiliki metode berbeda untuk mengambil data.
$ 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')
Terkadang lebih mudah untuk melintasi dokumen XML ketika Anda tidak perlu khawatir tentang ruang nama dan awalan ke elemen. Jika Anda ingin menghapusnya, Anda dapat menggunakan metode removeNamespaces()
pada pembaca.
$ reader = XmlReader :: fromString (...);
$ reader -> removeNamespaces ();
Saat mencari file besar, Anda dapat menggunakan metode lazy
atau collectLazy
yang akan mengembalikan generator hasil hanya menjaga satu item dalam memori pada satu waktu.
$ names = $ reader -> element ( ' name ' )-> lazy ();
foreach ( $ names as $ name ) {
//
}
Jika Anda menggunakan Laravel, Anda dapat menggunakan metode collect
and collectLazy
yang akan mengubah elemen menjadi koleksi Laravel/koleksi malas. Jika Anda tidak menggunakan Laravel, Anda dapat menginstal paket illuminate/collections
melalui komposer untuk menambahkan fungsi ini.
$ names = $ reader -> value ( ' name ' )-> collect ();
$ names = $ reader -> value ( ' name ' )-> collectLazy ();
Terkadang Anda mungkin ingin mencari elemen atau nilai tertentu di mana elemen berisi atribut tertentu. Anda dapat melakukan ini dengan memberikan argumen kedua untuk metode value
atau element
. Ini akan mencari elemen terakhir untuk atribut dan akan kembali jika cocok.
$ 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 adalah cara yang fantastis untuk mencari melalui XML. Dengan satu string, Anda dapat mencari elemen tertentu, dengan atribut atau indeks tertentu. Jika Anda tertarik mempelajari XPATH, Anda dapat mengklik di sini untuk cheatsheet yang bermanfaat.
Anda dapat menggunakan metode xpathValue
untuk menemukan nilai elemen tertentu dengan kueri XPath. Metode ini akan mengembalikan kelas Query
yang memiliki metode berbeda untuk mengambil data.
<?php
$ reader = XmlReader :: fromString (...);
$ reader -> xpathValue ( ' //person/favourite-songs/song[3] ' )-> sole (); // 'London Symfony Orchestra - Starfield Suite'
Anda dapat menggunakan metode xpathElement
untuk menemukan elemen tertentu dengan kueri XPath. Metode ini akan mengembalikan kelas Query
yang memiliki metode berbeda untuk mengambil data.
<?php
$ reader = XmlReader :: fromString (...);
$ reader -> xpathElement ( ' //person/favourite-songs/song[3] ' )-> sole (); // Element('London Symfony Orchestra - Starfield Suite')
PERINGATAN Karena keterbatasan dengan XPATH - metode di atas yang digunakan untuk meminta XPath tidak aman memori dan mungkin tidak cocok untuk dokumen XML besar.
Anda mungkin menemukan diri Anda dengan dokumen XML yang berisi atribut xmlns
yang tidak diprefiksasi - seperti ini:
< container xmlns = " http://example.com/xml-wrangler/person " xmlns : xsi = " http://www.w3.org/2001/XMLSchema-instance " />
Ketika ini terjadi, XML Wrangler akan secara otomatis menghapus ruang nama yang tidak ditentukan ini untuk meningkatkan kompatibilitas. Jika Anda ingin menyimpan ruang nama ini, Anda dapat menggunakan setXpathNamespaceMap
untuk memetakan setiap namespace XML yang tidak ditentukan.
$ reader = XmlReader :: fromString (...);
$ reader -> setXpathNamespaceMap ([
' root ' => ' http://example.com/xml-wrangler/person ' ,
]);
$ reader -> xpathValue ( ' //root:person/root:favourite-songs/root:song[3] ' )-> sole ();
Bagian ini pada dokumentasi ini adalah untuk menggunakan penulis XML.
Penggunaan paling dasar dari pembaca adalah menggunakan tombol string untuk nama dan nilai elemen untuk nilai elemen. Penulis menerima array bersarang tanpa batas untuk unsur -unsur bersarang.
use Saloon XmlWrangler XmlWriter ;
$ xml = XmlWriter :: make ()-> write ( ' root ' , [
' name ' => ' Sam ' ,
' twitter ' => ' @carre_sam ' ,
' facts ' => [
' favourite-song ' => ' Luke Combs - When It Rains It Pours '
],
]);
Kode di atas akan dikonversi menjadi XML berikut
<? 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 >
Saat menulis XML, Anda sering perlu mendefinisikan atribut dan ruang nama pada elemen Anda. Anda dapat menggunakan kelas Element
di array XML untuk menambahkan elemen dengan atribut atau namespace. Anda dapat mencampur kelas Element
dengan array dan nilai string lainnya.
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 ' ),
]);
Ini akan menghasilkan XML berikut
<? 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 >
Anda sering perlu mendefinisikan berbagai elemen. Anda dapat melakukan ini hanya dengan menyediakan berbagai nilai atau kelas elemen.
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 ' ),
],
],
]);
Ini akan menghasilkan XML berikut
<? 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 >
Terkadang Anda mungkin perlu mengubah nama elemen root. Ini dapat disesuaikan sebagai argumen pertama dari metode write
.
$ xml = XmlWriter :: make ()-> write ( ' custom-root ' , [...])
Jika Anda ingin menambahkan atribut dan ruang nama ke elemen root, Anda juga dapat menggunakan kelas RootElement
di sini.
use Saloon XmlWrangler Data RootElement ;
$ rootElement = RootElement :: make ( ' root ' )-> addNamespace ( ' soap ' , ' http://www.w3.org/2003/05/soap-envelope ' );
$ xml = XmlWriter :: make ()-> write ( $ rootElement , [...])
Jika Anda perlu menambahkan tag CDATA, Anda dapat menggunakan kelas 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! ' ),
]);
Ini akan menghasilkan XML berikut
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< root >
< name >Sam</ name >
< custom > <![CDATA[ Here is some CDATA content! ]]> </ custom >
</ root >
Terkadang Anda mungkin memiliki bagian dari XML yang akan Anda gunakan kembali di beberapa permintaan XML dalam aplikasi Anda. Dengan XML Wrangler, Anda dapat membuat elemen "komposable" di mana Anda dapat menentukan konten XML Anda di kelas yang dapat Anda gunakan kembali di seluruh aplikasi Anda. Perpanjang kelas Element
dan gunakan metode compose
statis yang dilindungi.
<?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 ,
]);
Ini akan menghasilkan XML seperti ini:
<? 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 >
Pengkodean XML default adalah utf-8
, versi default XML adalah 1.0
, dan standalone default adalah null
(XML parsers tidak menginterpretasikan tidak ada atribut mandiri yang sama seperti false
). Jika Anda ingin menyesuaikan ini, Anda dapat dengan metode setXmlEncoding
, setXmlVersion
, dan setXmlStandalone
pada penulis.
use Saloon XmlWrangler XmlWriter ;
$ writer = new XmlWriter ();
$ writer -> setXmlEncoding ( ' ISO-8859-1 ' );
$ writer -> setXmlVersion ( ' 2.0 ' );
$ writer -> setXmlStandalone ( true );
// $writer->write(...);
Hasil mana dalam deklarasi XML <?xml version="2.0" encoding="ISO-8859-1" standalone="yes"?>
.
Anda dapat menambahkan "instruksi pemrosesan" khusus ke XML dengan menggunakan metode addProcessingInstruction
.
use Saloon XmlWrangler XmlWriter ;
$ writer = new XmlWriter ();
$ writer -> addProcessingInstruction ( ' xml-stylesheet ' , ' type="text/xsl" href="base.xsl" ' );
$ xml = $ writer -> write ( ' root ' , [ ' name ' => ' Sam ' ]);
Ini akan menghasilkan XML berikut
<? xml version = " 1.0 " encoding = " utf-8 " ?>
<? xml-stylesheet type = " text/xsl " href = " base.xsl " ?>
< root >
< name >Sam</ name >
</ root >
Secara default XML yang ditulis tidak diminifikasi. Anda dapat memberikan argumen ketiga untuk metode write
untuk meminimalkan XML.
use Saloon XmlWrangler XmlWriter ;
$ xml = XmlWriter :: make ()-> write ( ' root ' , [...], minified: true );
XML Wrangler adalah pembungkus sederhana di sekitar dua perpustakaan yang sangat kuat yang melakukan banyak kerja keras. Kedua perpustakaan itu fantastis dan pantas mendapatkan bintang!