PHPackages                             xp-forge/address - 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. xp-forge/address

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

xp-forge/address
================

Creates objects from XML input streams while parsing them.

v7.0.0(8mo ago)27.8k[1 PRs](https://github.com/xp-forge/address/pulls)1BSD-3-ClausePHPPHP &gt;=7.4.0CI passing

Since Feb 12Pushed 8mo ago1 watchersCompare

[ Source](https://github.com/xp-forge/address)[ Packagist](https://packagist.org/packages/xp-forge/address)[ Docs](http://xp-framework.net/)[ RSS](/packages/xp-forge-address/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (4)Versions (24)Used By (1)

Address
=======

[](#address)

[![Build status on GitHub](https://github.com/xp-forge/address/workflows/Tests/badge.svg)](https://github.com/xp-forge/address/actions)[![XP Framework Module](https://raw.githubusercontent.com/xp-framework/web/master/static/xp-framework-badge.png)](https://github.com/xp-framework/core)[![BSD Licence](https://raw.githubusercontent.com/xp-framework/web/master/static/licence-bsd.png)](https://github.com/xp-framework/core/blob/master/LICENCE.md)[![Requires PHP 7.4+](https://raw.githubusercontent.com/xp-framework/web/master/static/php-7_4plus.svg)](http://php.net/)[![Supports PHP 8.0+](https://raw.githubusercontent.com/xp-framework/web/master/static/php-8_0plus.svg)](http://php.net/)[![Latest Stable Version](https://camo.githubusercontent.com/c0144d92f76bd933bf929b736901e4895a4259cacff2a35afe5afbacbf383361/68747470733a2f2f706f7365722e707567782e6f72672f78702d666f7267652f616464726573732f76657273696f6e2e737667)](https://packagist.org/packages/xp-forge/address)

Creates objects from XML input streams while parsing them. Yes, this still happens today 😉

Example
-------

[](#example)

Given the following two value objects:

```
class Book {
  public $name, $author;

  public function __construct(string $name, Author $author) {
    $this->name= $name;
    $this->author= $author;
  }
}

class Author {
  public $name;

  public function __construct(string $name) {
    $this->name= $name;
  }
}
```

...and this XML:

```

  A Short History of Nearly Everything

    Bill Bryson

```

...the following will map the XML to an object instance while reading it from the socket.

```
use util\address\{XmlStreaming, ObjectOf};

$socket= /* ... */

$stream= new XmlStreaming($socket);
$book= $stream->next(new ObjectOf(Book::class, [
  'name'   => fn($self) => $self->name= yield,
  'author' => fn($self) => $self->author= yield new ObjectOf(Author::class, [
    'name'   => fn($self) => $self->name= yield ?: '(unknown author)'; }
  ])
]);
```

Creating values
---------------

[](#creating-values)

Definitions are used to create structured data from the XML input. Here are all the implementations:

### ValueOf

[](#valueof)

Simplemost version which is given a seed value, which it can modify through the given address functions.

```
use util\address\{XmlStreaming, ValueOf};

// Parse into string 'Tim Taylor'
$stream= new XmlStreaming('Tim Taylor');
$name= $stream->next(new ValueOf(null, [
  '.' => fn(&$self) => $self= yield,
]);

// Parse into array ['More', 'Power']
$stream= new XmlStreaming('MorePower');
$name= $stream->next(new ValueOf([], [
  'tool' => fn(&$self) => $self[]= yield,
]);

// Parse into map ['id' => 6100, 'name' => 'more power']
$stream= new XmlStreaming('more power');
$book= $stream->next(new ValueOf([], [
  '@id' => fn(&$self) => $self['id']= (int)yield,
  '.'   => fn(&$self) => $self['name']= yield,
]);
```

### ObjectOf

[](#objectof)

Creates objects without invoking their constructors. Modifies the members directly, including non-public ones.

```
use util\address\{XmlStreaming, ObjectOf};

class Book {
  public $isbn, $name;
}

// Parse into Book(isbn: '978-0552151740', name: 'A Short History...')
$stream= new XmlStreaming('A Short History...');
$book= $stream->next(new ObjectOf(Book::class, [
  '@isbn' => fn($self) => $self->isbn= yield,
  'name'  => fn($self) => $self->name= yield,
]);
```

### RecordOf

[](#recordof)

Works with *record* classes, which are defined as being immutable and having an all-arg constructor. Modifies the named constructor arguments.

```
use util\address\{XmlStreaming, RecordOf};

class Book {
  public function __construct(private string $isbn, private string $name) { }

  public function isbn() { return $this->isbn; }
  public function name() { return $this->name; }
}

// Parse into Book(isbn: '978-0552151740', name: 'A Short History...')
$stream= new XmlStreaming('A Short History...');
$book= $stream->next(new RecordOf(Book::class, [
  '@isbn' => fn(&$args) => $args['isbn']= yield,
  'name'  => fn(&$args) => $args['name']= yield,
]);
```

Iteration
---------

[](#iteration)

Any `Address` instance can be iterated using the `foreach` statement. Using the [data sequences library](https://github.com/xp-forge/sequence) in combination with calling the `value()` method here's a way to parse an RSS feed's items:

```
use peer\http\HttpConnection;
use util\data\Sequence;
use util\Date;
use util\address\{XmlStream, ObjectOf};
use util\cmd\Console;

class Item {
  public $title, $description, $pubDate, $generator, $link, $guid;
}

$definition= new ObjectOf(Item::class, [
  'title'       => fn($self) => $self->title= yield,
  'description' => fn($self) => $self->description= yield,
  'pubDate'     => fn($self) => $self->pubDate= new Date(yield),
  'generator'   => fn($self) => $self->generator= yield,
  'link'        => fn($self) => $self->link= yield,
  'guid'        => fn($self) => $self->guid= yield,
]);

$conn= new HttpConnection('https://www.tagesschau.de/xml/rss2/');
$stream= new XmlStream($conn->get()->in());

Sequence::of($stream->pointers('//channel/item'))
  ->map(fn($pointer) => $pointer->value($definition))
  ->each(fn($item) => Console::writeLine('- ', $item->title, "\n  ", $item->link))
;
```

###  Health Score

46

—

FairBetter than 93% of packages

Maintenance60

Regular maintenance activity

Popularity26

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity73

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~183 days

Recently: every ~167 days

Total

22

Last Release

255d ago

Major Versions

v2.0.0 → v3.0.02021-10-24

v3.0.0 → v4.0.02021-11-01

v4.2.0 → v5.0.02021-11-14

v5.4.0 → v6.0.02024-02-04

v6.1.1 → v7.0.02025-09-05

PHP version history (4 changes)v0.2.0PHP &gt;=5.4.0

v0.4.0PHP &gt;=5.6.0

v2.0.0PHP &gt;=7.0.0

v7.0.0PHP &gt;=7.4.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/07d18d882c8b4aaf3466432f64018214f2771eda333202175431ee7233795376?d=identicon)[thekid](/maintainers/thekid)

---

Top Contributors

[![thekid](https://avatars.githubusercontent.com/u/696742?v=4)](https://github.com/thekid "thekid (246 commits)")

---

Tags

php7php8xmlxml-stream-parsingxp-frameworkmodulexp

### Embed Badge

![Health badge](/badges/xp-forge-address/health.svg)

```
[![Health](https://phpackages.com/badges/xp-forge-address/health.svg)](https://phpackages.com/packages/xp-forge-address)
```

###  Alternatives

[xp-framework/compiler

XP Compiler

2026.0k9](/packages/xp-framework-compiler)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
