Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/josemmo/uxml

Uncomplicated XML manipulation library for PHP
https://github.com/josemmo/uxml

php xml xml-manipulation xml-parser

Last synced: 3 months ago
JSON representation

Uncomplicated XML manipulation library for PHP

Awesome Lists containing this project

README

        

# Uncomplicated XML
[![Build Status](https://github.com/josemmo/uxml/workflows/CI/badge.svg)](https://github.com/josemmo/uxml/actions)
[![Latest Version](https://img.shields.io/packagist/v/josemmo/uxml)](https://packagist.org/packages/josemmo/uxml)
[![Minimum PHP Version](https://img.shields.io/packagist/php-v/josemmo/uxml)](#installation)
[![License](https://img.shields.io/github/license/josemmo/uxml)](LICENSE)

UXML is an *extremely* simple PHP library for manipulating XML documents with ease while keeping overhead to a bare minimum.

It consist of just a single class which uses the PHP built-in `DOMElement` and `DOMDocument` classes under the hood.

## Installation

### Using Composer
```
composer require josemmo/uxml
```

### Without Composer
Download source files from the GitHub repository:
```
git clone https://github.com/josemmo/uxml.git
```

Use the UXML class in your app:
```php
use UXML\UXML;
require_once __DIR__ . "/uxml/src/UXML.php";
```

## FAQ
**Why use this instead of [sabre/xml](https://github.com/sabre-io/xml) or [FluidXML](https://github.com/servo-php/fluidxml)?**\
Both those options are great and if they fit your project you should definetely use them! However, in my case I needed something more lightweight to put on top of [LibXML's DOM](https://www.php.net/manual/en/book.dom.php) to provide an alternative syntax.

**Is UXML compatible with `DOMElement`?**\
Yes, indeed! You can get the original `DOMElement` instance from an `UXML` object and vice versa.

**I want UXML to do "X". Can you implement it?**\
My main goal with this project is not to implement all possible behaviors in the XML specification, you can use the DOM or SimpleXML libraries for that.

## Usage

### Create a new document
UXML does not distinguish between XML documents (`DOMDocument`) and elements (`DOMElement`). Instead, you can create a new document like so:
```php
$xml = \UXML\UXML::newInstance('RootTagName');
```

You can also wrap an already existing `DOMElement`:
```php
$domElement = new DOMElement('TagName');
$xml = \UXML\UXML::fromElement($domElement);
```

### Load an XML document from source
By loading an XML string, UXML will return the root element of the document tree:
```php
$source = <<
Banana
Apple
Tomato

XML;
$xml = \UXML\UXML::fromString($source);
```

### Add elements to a node
When adding an element, UXML will return a reference to the newly created element:
```php
$xml = \UXML\UXML::newInstance('Parent');
$child = $xml->add('Child');
echo $child; //
echo $xml; //
```

You can also define a value:
```php
$child = $xml->add('Child', 'Hello World!');
echo $child; // Hello World!
```

And even attributes or namespaces:
```php
$feed = \UXML\UXML::newInstance('feed', null, [
'xmlns' => 'http://www.w3.org/2005/Atom'
]);
echo $feed; //

$link = $feed->add('link', 'Wow!', [
'href' => 'https://www.example.com'
]);
echo $link; // Wow!
```

### Element chaining
Because with every element insertion a reference to the new element is returned, you can chain multiple of these calls to create a tree:
```php
$xml = \UXML\UXML::newInstance('people');
$xml->add('person')->add('name', 'Jane Doe');
echo $xml; //
//
// Jane Doe
//
//
```

### Export XML source
Besides casting `UXML` objects to a `string`, there is a method for exporting the XML source of an element and its children:
```php
$xml->asXML();
```

By default, exported strings include an XML declaration (except when casting `UXML` instances to a `string`).

### Find XML elements
UXML allows you to use XPath 1.0 queries to get a particular element from a document:
```php
$xml = \UXML\UXML::newInstance('person');
$xml->add('name', 'Jane');
$xml->add('surname', 'Doe');
$xml->add('color', 'green', ['hex' => '#0f0']);

echo $xml->get('*[@hex]'); // green
var_dump($xml->get('birthday')); // NULL
```

Or even multiple elements:
```php
$xml = \UXML\UXML::fromString('123');
foreach ($xml->getAll('b') as $elem) {
echo "Element says: " . $elem->asText() . "\n";
}
```

Note all XPath queries are **relative to current element**:
```php
$source = <<
Inception
2010

Christopher
Nolan
1970

XML;
$xml = \UXML\UXML::fromString($source);

echo $xml->get('director/year'); // 1970
echo $xml->get('director')->get('year'); // 1970
echo $xml->get('year'); // 2010
echo $xml->get('director')->get('//year'); // 2010
```

### Remove XML elements
Elements can be removed from the XML tree by calling the `remove()` method on them.
After an element is removed, it becomes unusable:
```php
$source = <<

Alpha


1,000,000 USD

XML;
$xml = \UXML\UXML::fromString($source);
$xml->get('confidential')->remove();
echo $xml; // Alpha
```

### Namespaces
Namespaces are assigned in the same way as other attributes:
```php
$xml->add('TagName', null, [
'xmlns' => 'https://example.com',
'xmlns:abc' => 'urn:abc',
'attribute' => 'value'
])->add('abc:Child', 'Name');
echo $xml; //
// Name
//
```

However, when querying elements, the prefix defined in the document may not be the one you are expecting:
```php
$xml = \UXML\UXML::fromString('');
echo $xml->get('ns:b'); //
echo $xml->get('abc:b'); // Is NULL as the prefix does not exist
```

To fix this, you can make use of [clark notation](https://sabre.io/xml/clark-notation/) inside the XPath query:
```php
echo $xml->get('{urn:abc}b'); //
```

### Advanced XML manipulation
For any other document manipulation outside the scope of this library, you can always interact with the `DOMElement` instance:
```php
$xml = \UXML\UXML::newInstance('Test');
$xml->element(); // Returns a [DOMElement] object
```