vondrasoft / xml-serializer
Transform arrays to xml and back.
v1.0.1
2021-12-31 08:30 UTC
Requires
- php: >=8.0
- ext-dom: *
- ext-libxml: *
- ext-simplexml: *
Requires (Dev)
- jetbrains/phpstorm-attributes: ^1.0
- phpstan/phpstan: ^1.2.0
- phpunit/phpunit: ^9.5
- slevomat/coding-standard: ^7.0
- squizlabs/php_codesniffer: *
README
This package serialize xml to collection (arrays, json) and back for your apis.
It is compatible (and tested) with PHP 8.0+. There is 100% unit test coverage with codesniffer and phpstan at maximum level.
Installation
Add vondrasoft/xml-serializer
to your composer.json
file or:
composer require vondrasoft/xml-serializer
Usage
Serialize array to xml
<?php use XmlSerializer\Factory\ElementCollectionFactory; use XmlSerializer\Inspector\CollectionInspector; use XmlSerializer\Serializer\XmlSerializer; use XmlSerializer\XmlSerializerManager; $input = [ [ 'name' => 'test', 'value' => [ [ 'cdata' => true, 'name' => 'element', 'attributes' => [ [ 'name' => 'param1', 'value' => 'value1', ], [ 'name' => 'param2', 'value' => 'value2', ], ], 'value' => [ [ 'name' => 'element1', 'attributes' => [ [ 'name' => 'param', 'value' => '10', ], ], 'value' => 'serializer', ], ], ], ], ], ]; $manager = new XmlSerializerManager(new XmlSerializer(), new CollectionInspector()); echo $manager->getXmlFromArray($input);
Output
<test> <element param1="value1" param2="value2"> <![CDATA[<element1 param="10">serializer</element1>]]> </element> </test>
Deserialize XML to collection
<?php use XmlSerializer\Factory\ElementCollectionFactory; use XmlSerializer\Serializer\XmlSerializer; $inputXml = ' <vehicle> <brand code="xx">Xexe</brand> <data code="dataset"> <model type="string">BestModel</model> <risk> <optional>Zero</optional> <primary>First</primary> </risk> </data> </vehicle>'; $serializer = new XmlSerializer(); $collection = $serializer->deserialize($inputXml); // collections implements JsonSerializable interface, so you can transform to json them easily echo json_encode($collection);
Output
[ { "name": "vehicle", "value": [ { "name": "brand", "attributes": [ { "name": "code", "value": "xx" } ], "value": "Xexe" }, { "name": "data", "attributes": [ { "name": "code", "value": "dataset" } ], "value": [ { "name": "model", "attributes": [ { "name": "type", "value": "string" } ], "value": "BestModel" }, { "name": "risk", "value": [ { "name": "optional", "value": "Zero" }, { "name": "primary", "value": "First" } ] } ] } ] } ]
Create collection manually
<?php use XmlSerializer\Collection\ElementCollection; use XmlSerializer\Factory\ElementCollectionFactory; use XmlSerializer\Model\Element; use XmlSerializer\Serializer\XmlSerializer; $collection = new ElementCollection(); $firstElement = (new Element('firstElement'))->setValue('firstValue'); $secondElement = (new Element('secondElement'))->setValue('secondValue'); $collection ->addElement($firstElement) ->addElement($secondElement); $xmlCollection = new ElementCollection(); $rootElement = (new Element('main'))->setElements($collection); $xmlCollection->addElement($rootElement); $serializer = new XmlSerializer(); $output = $serializer->serialize($xmlCollection); echo $output;
Output
<main> <firstElement>firstValue</firstElement> <secondElement>secondValue</secondElement> </main>
Collection inspector
<?php use XmlSerializer\Factory\ElementCollectionFactory; use XmlSerializer\Inspector\CollectionInspector; use XmlSerializer\Serializer\XmlSerializer; $inputXml = ' <vehicle> <brand code="xx">Xexe</brand> <data code="dataset"> <model type="string">BestModel</model> <risk> <optional>Zero</optional> <primary>First</primary> </risk> </data> </vehicle>'; $serializer = new XmlSerializer(); $collection = $serializer->deserialize($inputXml); $inspector = new CollectionInspector($collection); // will print "BestModel" echo $inspector->getElementByPath('vehicle.data.model')->getValue();
There is problem about elements with same name. So you can specify element by an index.
<?php use XmlSerializer\Factory\ElementCollectionFactory; use XmlSerializer\Inspector\CollectionInspector; use XmlSerializer\Serializer\XmlSerializer; $inputXml = ' <notepad> <param>first</param> <param>second</param> <param> <note>one</note> <note>two</note> </param> </notepad> '; $serializer = new XmlSerializer(); $collection = $serializer->deserialize($inputXml); $inspector = new CollectionInspector($collection); // will print "first" echo $inspector->getElementByPath('notepad.param[0]')->getValue(); // will print "second" echo $inspector->getElementByPath('notepad.param[1]')->getValue(); // will print "two" echo $inspector->getElementByPath('notepad.param[2].note[1]')->getValue();
XmlSerializerManager
This is main class from the package, you can inject it to your services by dependency injection and simple use it.
<?php use XmlSerializer\Inspector\CollectionInspector; use XmlSerializer\Serializer\XmlSerializer; use XmlSerializer\XmlSerializerManager; $inputXml = ' <notepad> <param>first</param> <param>second</param> <param> <note>one</note> <note>two</note> </param> </notepad> '; $manager = new XmlSerializerManager(new XmlSerializer(), new CollectionInspector()); // you can call serializer methods by getSerializer ... $collection = $manager->getSerializer()->deserialize($inputXml); // but you can use it directly on the manager level $array = $manager->getArrayFromXml($inputXml); // will print the same array, like calling $collection->toArray(); var_dump($array); // you can get json from xml and etc.. getXmlFromArray, getXmlFromJson, getArrayFromXml $json = $manager->getJsonFromXml($inputXml); //you can use inspector from manager by call $inspector = $manager->getCollectionInspector(); // you must set the collection if you are using dependency injection without inject collection to constructor $inspector->setCollection($collection); $element = $inspector->getElementByPath('....');