Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/eliashaeussler/valinor-xml
🔖 XML source for cuyz/valinor
https://github.com/eliashaeussler/valinor-xml
composer library mapper php source valinor xml
Last synced: about 8 hours ago
JSON representation
🔖 XML source for cuyz/valinor
- Host: GitHub
- URL: https://github.com/eliashaeussler/valinor-xml
- Owner: eliashaeussler
- License: gpl-3.0
- Created: 2024-06-13T21:01:58.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2024-11-04T14:05:41.000Z (3 days ago)
- Last Synced: 2024-11-04T15:19:56.433Z (3 days ago)
- Topics: composer, library, mapper, php, source, valinor, xml
- Language: PHP
- Homepage:
- Size: 242 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Codeowners: CODEOWNERS
Awesome Lists containing this project
README
[![Code example](docs/img/header.svg)](#-installation)
# XML source for `cuyz/valinor`
[![Coverage](https://img.shields.io/coverallsCoverage/github/eliashaeussler/valinor-xml?logo=coveralls)](https://coveralls.io/github/eliashaeussler/valinor-xml)
[![Maintainability](https://img.shields.io/codeclimate/maintainability/eliashaeussler/valinor-xml?logo=codeclimate)](https://codeclimate.com/github/eliashaeussler/valinor-xml/maintainability)
[![CGL](https://img.shields.io/github/actions/workflow/status/eliashaeussler/valinor-xml/cgl.yaml?label=cgl&logo=github)](https://github.com/eliashaeussler/valinor-xml/actions/workflows/cgl.yaml)
[![Tests](https://img.shields.io/github/actions/workflow/status/eliashaeussler/valinor-xml/tests.yaml?label=tests&logo=github)](https://github.com/eliashaeussler/valinor-xml/actions/workflows/tests.yaml)
[![Supported PHP Versions](https://img.shields.io/packagist/dependency-v/eliashaeussler/valinor-xml/php?logo=php)](https://packagist.org/packages/eliashaeussler/valinor-xml)A Composer library that provides an additional XML source for use with
the popular [`cuyz/valinor`](https://github.com/CuyZ/Valinor) library.
This allows to easily map XML files or contents to any signature supported
by Valinor, e.g. objects or special array shapes. It leverages the
[`mtownsend/xml-to-array`](https://github.com/mtownsend5512/xml-to-array)
library to convert raw XML to a reusable array structure.## 🔥 Installation
[![Packagist](https://img.shields.io/packagist/v/eliashaeussler/valinor-xml?label=version&logo=packagist)](https://packagist.org/packages/eliashaeussler/valinor-xml)
[![Packagist Downloads](https://img.shields.io/packagist/dt/eliashaeussler/valinor-xml?color=brightgreen)](https://packagist.org/packages/eliashaeussler/valinor-xml)```bash
composer require eliashaeussler/valinor-xml
```## ⚡ Usage
Given the following XML:
```xml
Dr. Zane Stroman
439 Karley Loaf
17916
West Judge
Falkland Islands (Malvinas)
827-986-5852
```
These are the resulting classes:
```php
final readonly class Address
{
public function __construct(
public string $street,
public string $postcode,
public string $city,
public string $country,
) {}
}final readonly class Contact
{
public function __construct(
public string $phone,
) {}
}final readonly class Person
{
public function __construct(
public string $name,
public Address $address,
public Contact $contact,
) {}
}
```### Mapping from XML string
In order to map the given XML to the `Person` class, you need
to follow these three steps:1. Create a new mapper as written in [Valinor's documentation](https://valinor.cuyz.io/latest/getting-started/)
2. Parse and prepare your XML using the shipped [`XmlSource`](src/Mapper/Source/XmlSource.php)
3. Use the mapper to map your XML to the `Person` class```php
use CuyZ\Valinor;
use EliasHaeussler\ValinorXml;$mapper = (new Valinor\MapperBuilder())->mapper();
$source = ValinorXml\Mapper\Source\XmlSource::fromXmlString($xml);
$person = $mapper->map(Person::class, $source); // instanceof Person
```The resulting object will look something like this:
```
object(Person)#180 (3) {
["name"]=>
string(16) "Dr. Zane Stroman"
["address"]=>
object(Address)#135 (4) {
["street"]=>
string(15) "439 Karley Loaf"
["postcode"]=>
string(5) "17916"
["city"]=>
string(10) "West Judge"
["country"]=>
string(27) "Falkland Islands (Malvinas)"
}
["contact"]=>
object(Contact)#205 (1) {
["phone"]=>
string(12) "827-986-5852"
}
}
```### Mapping from XML file
The XML can also be read from an external file:
```php
use CuyZ\Valinor;
use EliasHaeussler\ValinorXml;$mapper = (new Valinor\MapperBuilder())->mapper();
$source = ValinorXml\Mapper\Source\XmlSource::fromXmlFile($file);
$person = $mapper->map(Person::class, $source); // instanceof Person
```### Convert nodes to collections
Sometimes it might be necessary to always convert XML nodes to
collections. Given the following XML:```xml
```
Let's assume you want to map this XML to the following class:
```php
final readonly class Community
{
/**
* @param list $member
*/
public function __construct(
public array $member,
) {}
}
```You will recognize that this does not work as expected when using the
above mapping method:```php
use CuyZ\Valinor;
use EliasHaeussler\ValinorXml;$mapper = (new Valinor\MapperBuilder())->mapper();
$source = ValinorXml\Mapper\Source\XmlSource::fromXmlFile($file);
$person = $mapper->map(Community::class, $source); // throws exception
```It will instead throw an exception like this:
```
CuyZ\Valinor\Mapper\TypeTreeMapperError: Could not map type `Community` with value array{member: array{…}}.
```This is because the XML converter does not know whether `` should
be a collection or if it's just a "normal" node. That's why the `XmlSource`
provides an appropriate method to convert such nodes to collections:```php
use CuyZ\Valinor;
use EliasHaeussler\ValinorXml;$mapper = (new Valinor\MapperBuilder())->mapper();
$source = ValinorXml\Mapper\Source\XmlSource::fromXmlFile($file)
->asCollection('member')
;
$person = $mapper->map(Community::class, $source); // instanceof Community
```The resulting object will look something like this:
```
object(Community)#76 (1) {
["member"]=>
array(1) {
[0]=>
object(Person)#126 (3) {
["name"]=>
string(16) "Dr. Zane Stroman"
["address"]=>
object(Address)#170 (4) {
["street"]=>
string(15) "439 Karley Loaf"
["postcode"]=>
string(5) "17916"
["city"]=>
string(10) "West Judge"
["country"]=>
string(27) "Falkland Islands (Malvinas)"
}
["contact"]=>
object(Contact)#252 (1) {
["phone"]=>
string(12) "827-986-5852"
}
}
}
}
```However, this is only relevant if only one node of the collection
exists in your XML. If the XML contains more than one node, the XML
converter properly converts them to a collection:```php
use CuyZ\Valinor;
use EliasHaeussler\ValinorXml;$xml = <<
XML;
$mapper = (new Valinor\MapperBuilder())->mapper();
$source = ValinorXml\Mapper\Source\XmlSource::fromXmlString($xml);
$person = $mapper->map(Community::class, $source); // instanceof Community
```## 🧑💻 Contributing
Please have a look at [`CONTRIBUTING.md`](CONTRIBUTING.md).
## ⭐ License
This project is licensed under [GNU General Public License 3.0 (or later)](LICENSE).