XML writer and parser utilities
, (*1)
, (*2)
Installing
$ composer require lucid/xml
Testing
Run tests with:, (*3)
$ ./vendor/bin/phpunit
The Parser
The Parser class can parse xml string, files, DOMDocuments, and DOMElements
into a php array., (*4)
Parsing xml strings
<?php
use Lucid\Xml\Parser;
$parser = new Parser;
$parser->parse('<data><foo>bar</foo></data>');
Parsing xml files
<?php
use Lucid\Xml\Parser;
$parser = new Parser;
$parser->parse('/path/to/data.xml');
Parsing a DOMDocument
<?php
use Lucid\Xml\Parser;
$parser = new Parser;
$parser->parseDom($dom);
Parsing a DOMElement
<?php
use Lucid\Xml\Parser;
$parser = new Parser;
$parser->parseDomElement($element);
Parser Options
Dealing with Attributes
Xml attributes are captured as an deticated section within the actual node data.
The section key defaults to @attributes, but can be changed using the setAttributesKey method., (*5)
<?php
use Lucid\Xml\Parser;
$xml = '<data><node id="1">some text</node></data>'
$parser = new Parser;
$parser->setAttributesKey('__attrs__');
$parser->parse($xml);
['data' => ['node' => ['__attrs__' => ['id' => 1], 'value' => 'some text']]];
Merging attributes
Setting Parser::mergeAttributes(true) will merge any attributes as key/value
into the data set., (*6)
$parser->setMergeAttributes(true);
$parser->parse($xml);
The above example will output something simmilar to this:, (*7)
['data' => ['node' => ['id' => 1, 'value' => 'some text']]];
Normalizing keys
You may specifay how keys are being transformed by setting a key normalizer callback., (*8)
The default normalizer transforms dashes to underscores and camelcase to snakecase notation., (*9)
<?php
use Lucid\Xml\Parser;
$parser = new Parser;
$parser->setKeyNormalizer(function ($key) {
// do string transfomations
return $key;
});
$parser->parseDomElement($element);
Set index key
This forces the parser to treat nodes with a nodeName of the given key to be
handled as list., (*10)
<?php
use Lucid\Xml\Parser;
$parser = new Parser;
$parser->setIndexKey('item');
Set a pluralizer
By default the parser will parse xml structures like, (*11)
<entries>
<entry>1</entry>
<entry>2</entry>
</entries>
To something like:, (*12)
<?php
['entries' => ['entry' => [1, 2]]]
Setting a pluralizer can fix this., (*13)
Note, that a pluralizer can be any callable that takes a string and returns
a string., (*14)
<?php
$parser->setPluralizer(function ($string) {
if ('entry' === $string) {
return 'entries';
}
});
<?php
['entries' => [1, 2]]
The Writer
Dumping php data to a xml string
<?php
use Lucid\Xml\Writer;
$writer = new Writer;
$data = [
'foo' => 'bar'
];
$writer->dump($data); // <root><foo>bar</foo></root>
// set the xml root node name:
$writer->dump($data, 'data'); // <data><foo>bar</foo></data>
Dumping php data to a DOMDocument
Note: this will create an instance of Lucid\Xml\Dom\DOMDocument., (*15)
<?php
use Lucid\Xml\Writer;
$writer = new Writer;
$data = [
'foo' => 'bar'
];
$dom = $writer->writeToDom($data);
Writer options
Set the normalizer instance
Normaly, the NormalizerInterface implementation is set for you when instantiating a new Writer, however you can set your own normalizer instance., (*16)
Note: the normalizer must implement the Lucid\Xml\Normalizer\NormalizerInterface interface., (*17)
<?php
use Lucid\Xml\Writer;
use Lucid\Xml\Normalizer\Normalizer;
$writer = new Writer(new Normalizer);
// or
$writer->setNormalizer($myNormalizer);
Set the inflector
The inflector is the exact oppoite of the Parser's pluralizer. It singularizes
strings., (*18)
<?php
$writer->setInflector(function ($string) {
if ('items' === $string) {
return 'item';
}
});
Set the document encoding
Default encoding is UTF-8., (*19)
<?php
$writer->setEncoding($encoding); // string
Set an attribute key map
This is usefull if you want to output certain keys as xml attribute, (*20)
<?php
$writer->setKeyMap([
'nodeName' => ['id', 'entry'] // nested keys 'id' and 'entry' of the key
element 'nodeName' will be set as attributes instead of childnodes.
]);
Note: you can also use use addMappedAttribute($nodeName, $attributeName) to add more mapped attributes., (*21)
Set value keys
<?php
$data = [
'foo' => [
'@attributes' => [
'bar' => 'baz'
],
'value' => 'tab'
]
];
The data structure above would dump the following xml string, (*22)
<foo bar="baz"><value>tab</value></foo>
However, if you need the value node as actual value of the parent node, you may
use Writer::useKeyAsValue(string $key) to do so, (*23)
<?php
$writer->useKeyAsValue('value');
$writer->dump($data);
now dumps:, (*24)
<foo bar="baz">tab</foo>
Writing indexed array structure
Indexed arrays will create xml structures like the example below:, (*25)
$data = ['data' => [1, 2, 3]];
$writer->dump($data);
<data>
<item>1</item>
<item>2</item>
<item>3</item>
</data>
You can change the node names associated with indexed items by using the
useKeyAsIndex(string $key) method., (*26)
$writer->useKeyAsIndex('thing');
$writer->dump($data);
<data>
<thing>1</thing>
<thing>2</thing>
<thing>3</thing>
</data>
Writing arrays with none valid index keys
Arrays containing invalid indices (e.g. unordererd lists) will be treated
slightly different., (*27)
$data = ['data' => [1 => 'foo', 4 => 'bar', 3 => 'baz']];
$writer->dump($data);
<data>
<item index="1">foo</item>
<item index="4">bar</item>
<item index="3">baz</item>
</data>