PHPackages                             eliashaeussler/valinor-xml - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. eliashaeussler/valinor-xml

ActiveLibrary[Parsing &amp; Serialization](/categories/parsing)

eliashaeussler/valinor-xml
==========================

XML source for cuyz/valinor

2.0.0(7mo ago)2136.7k↓41.7%[2 issues](https://github.com/eliashaeussler/valinor-xml/issues)1GPL-3.0-or-laterPHPPHP ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0CI passing

Since Jun 14Pushed yesterday1 watchersCompare

[ Source](https://github.com/eliashaeussler/valinor-xml)[ Packagist](https://packagist.org/packages/eliashaeussler/valinor-xml)[ RSS](/packages/eliashaeussler-valinor-xml/feed)WikiDiscussions main Synced yesterday

READMEChangelog (6)Dependencies (10)Versions (11)Used By (1)

[![Code example](docs/img/header.svg)](#-installation)

XML source for `cuyz/valinor`
=============================

[](#xml-source-for-cuyzvalinor)

[![Coverage](https://camo.githubusercontent.com/95b3258f03327c6e7c120d128f1bdd4a05e3f31e8abaf5619795b247e7c355ec/68747470733a2f2f696d672e736869656c64732e696f2f636f766572616c6c73436f7665726167652f6769746875622f656c6961736861657573736c65722f76616c696e6f722d786d6c3f6c6f676f3d636f766572616c6c73)](https://coveralls.io/github/eliashaeussler/valinor-xml)[![CI](https://camo.githubusercontent.com/693b04145bc681cd13b553f80227fa4d2b9425791519bdc26544a28dd09075e4/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f656c6961736861657573736c65722f76616c696e6f722d786d6c2f63692e79616d6c3f6c6162656c3d4349266c6f676f3d676974687562)](https://github.com/eliashaeussler/valinor-xml/actions/workflows/ci.yaml)[![Supported PHP Versions](https://camo.githubusercontent.com/7d73646d76dcf60331d9c09c85ce5e39fac9b6c25d99a9d88a3832b97046fd73/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f656c6961736861657573736c65722f76616c696e6f722d786d6c2f7068703f6c6f676f3d706870)](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
--------------

[](#-installation)

[![Packagist](https://camo.githubusercontent.com/f7e73492a9a1e2f595ae8e7a5334841c379959654ecad8c65bdfc280522e5140/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f656c6961736861657573736c65722f76616c696e6f722d786d6c3f6c6162656c3d76657273696f6e266c6f676f3d7061636b6167697374)](https://packagist.org/packages/eliashaeussler/valinor-xml)[![Packagist Downloads](https://camo.githubusercontent.com/28741ff0e2d0f57a4fb206311be49db578ce909b2da178bb7251c4d0d19c7c1d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f656c6961736861657573736c65722f76616c696e6f722d786d6c3f636f6c6f723d627269676874677265656e)](https://packagist.org/packages/eliashaeussler/valinor-xml)

```
composer require eliashaeussler/valinor-xml
```

⚡ Usage
-------

[](#-usage)

Given the following XML:

```

    Dr. Zane Stroman

        439 Karley Loaf
        17916
        West Judge
        Falkland Islands (Malvinas)

        827-986-5852

```

These are the resulting classes:

```
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

[](#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

```
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

[](#mapping-from-xml-file)

The XML can also be read from an external file:

```
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

[](#convert-nodes-to-collections)

Sometimes it might be necessary to always convert XML nodes to collections. Given the following XML:

```

```

Let's assume you want to map this XML to the following class:

```
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:

```
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:

```
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:

```
use CuyZ\Valinor;
use EliasHaeussler\ValinorXml;

$xml =
