mleczek/xml

Transform PHP object to XML

v1.2.0 2017-01-17 21:58 UTC

This package is auto-updated.

Last update: 2024-11-05 04:59:57 UTC


README

Latest Stable Version Build Status Coverage Status License

The goal of the this library is to provide an easy way to respond XML by REST API.

Installation

Require this package with composer:

composer require mleczek/xml

Basic concepts

Class may be converted to XML using Mleczek\Xml\XmlConverter which implements the __toString, outerXml and innerXml methods returning XML as string:

$dog = new Dog();
$converter = new XmlConverter($dog);
$outerXml = (string)$converter;
$outerXml = $converter->outerXml(); // equals __toString
$innerXml = $converter->innerXml();

Library contains also the shorthand to cast objects to XML string using Mleczek\Xml\XmlConvertible trait (or helper functions):

use Mleczek\Xml\Xmlable;
use Mleczek\Xml\XmlConvertible;

class Dog
{
    use XmlConvertible;
    
    public $id = 5;
}

Mleczek\Xml\XmlConvertible implements the toXml method (also available as a helper function) which returns the outer XML string (skipped <?xml version="1.0" encoding="UTF-8"?> part in examples for better readability):

$dog = new Dog();
$xml = $dog->toXml(); // returns <result><id>5</id></result>
$xml = toXml($dog);   // without using XmlConvertible trait

By default root elements is <result>, you can change it calling toXmlAs method:

$dog = new Dog();
$xml = $dog->toXmlAs('dog'); // returns <dog><id>5</id></dog>
$xml = toXmlAs($dog, 'dog'); // without using XmlConvertible trait

Above examples use Mleczek\Xml\StructureAnalyser class to determine the output XML structure, to get more control you can implement the Mleczek\Xml\Xmlable interface with xml method:

use Mleczek\Xml\Xmlable;

class Dog implements Xmlable
{
    public function xml()
    {
        // XML Body...
    }
}

The XML body describes the ouput XML and will be described in the next chapter. Also the toXml method accepts optionally one argument (array) which can be used to control the XML body structure:

$dog = new Dog();
$xml = $dog->toXml(['cat']); // returns <cat/>

XML Body

This chapter describe the data which should by returned by the xml method.

XML Body can be implemented using 3 ways:

Array

The meta language which allow defining XML body, including:

Elements

The basic example return self-closing root element:

public function xml()
{
    // <dog/>
    return ['dog'];
}

You can add <name> node to the <dog> root using:

public function xml()
{
    // <dog><name>{$this->full_name}</name></dog>
    return [
        'dog' => [
            'name' => 'full_name'
        ]
    ];
}

As you can see above if you define value equal full_name then XmlConverter will look for full_name property in the object (casted to string). If property stores other object or array then you can retrieve nested property/key using dot notation address.city (equals $this->address->city or $this->address['city']).

You can also define more elements, self-closing elements and constant values:

public function xml()
{
    // <dog><hau/><hau2/><id>5</id></dog>
    return [
        'dog' => [
            'hau',          // self-closing element
            'hau2' => null, // self-closing element #2
            'id' => '=5',   // use "=" prefix for constant values
        ]
    ];
}

You can also merge arrays (without using PHP functions) and use conditional output:

public function xml()
{
    $extra_elements = [];
    if($this->isSuperDog()) {
        $extra_elements = ['hau_power' => 5];
    }

    // $this->isSuperDog():
    // true: <dog><hau/><hau_power>5</hau_power></dog>
    // false: <dog><hau/></dog>
    return [
        'dog' => [
            'hau' => true,   // true -> self-closing element
            'miau' => false, // false -> skip element
            $extra_elements, // merge arrays
        ]
    ];
}

Attributes

Attributes works like the elements, the only difference is that you have to prepend the name with "@" prefix.

public function xml()
{
    // <dog name="{$this->full_name}" canHau id="5"/>
    return [
        'dog' => [
            '@name' => 'full_name' 
            '@canHau',            // without value
            '@id' => '=5',        // use "=" prefix for constant values
        ]
    ];
}

Of course you can mix elements with attributes:

public function xml()
{
    // <dog canHau><id>5</id></dog>
    return [
        'dog' => [
            '@canHau',
            'id' => '=5'
        ]
    ];
}

String

Build and return plain XML string:

use Mleczek\Xml\Xmlable;

class Dog implements Xmlable
{
    public function xml()
    {
        return '<dog/>';
    }
}

XmlElement

Not recommended and not documented. See source code for more information.

XML Declaration

Using toXml method provided with Mleczek\Xml\XmlConvertible trait (or equivalent helper functions) automatically add XML declaration:

<?xml version="1.0" encoding="UTF-8"?>

Above declaration is available as constant value at Mleczek\Xml\XmlElement::XmlDeclaration.

Contributing

Thank you for considering contributing! If you would like to fix a bug or propose a new feature, you can submit a Pull Request.

License

The library is licensed under the MIT license.