mblarsen / array-xml
A simple yet expressive array syntax for building XML files
0.1.0
2019-11-21 09:53 UTC
Requires
- php: >=7.2
Requires (Dev)
- phpunit/phpunit: ^8
This package is auto-updated.
Last update: 2024-12-21 21:52:49 UTC
README
Because DOMDocument and SimpleXML sucks
- Easily build XML with associative arrays
- Succinct syntax for naming child elements, adding attributes, and more
- You can combine with
DOMDocument
if you really have to
Examples
- Easy to create attributes
- Children takes name from parent by default
ArrayToXML::toXML( 'Order@version=2.0' => [ 'ID@type=SKU' => 1234, 'Lines' => [ ['item' => 'ABC', 'qty' => 3], ['item' => 'DEF', 'qty' => 1], ] ] );
Yields:
<?xml version="1.0"?> <Order version="2.0"> <ID type="SKU">1234</ID> <Lines> <Line> <item>ABC</item> <qty>3</qty> </Line> <Line> <item>DEF</item> <qty>1</qty> </Line> </Lines> </Order>
- Using
|
you can specify a differnt name of the children
ArrayToXML::toXML( 'Order' => [ 'ID' => 1234, 'Lines|OrderLine' => [ ['item' => 'ABC', 'qty' => 3], ['item' => 'DEF', 'qty' => 1], ] ] );
Yields:
<?xml version="1.0"?> <Order> <ID>1234</ID> <Lines> <OrderLine> <item>ABC</item> <qty>3</qty> </OrderLine> <OrderLine> <item>DEF</item> <qty>1</qty> </OrderLine> </Lines> </Order>
- Using
name_mappers
you can use, index and child values to construct the child element name and attributes
ArrayToXML::toXML( 'Order' => [ 'ID' => 1234, 'Lines' => [ ['item' => 'ABC', 'qty' => 3], ['item' => 'DEF', 'qty' => 1], ] ], [ 'name_mappers' => [ 'Line' => function ($name, $index, $value) { return $name . '@number=' . ($index + 1); } ] ] );
Yields:
<?xml version="1.0"?> <Order> <ID>1234</ID> <Lines> <Line number="1"> <item>ABC</item> <qty>3</qty> </Line> <Line number="2"> <item>DEF</item> <qty>1</qty> </Line> </Lines> </Order>
- "Flatten" the parent element and put its children in its place using
<
.
ArrayToXML::toXML( 'Order' => [ 'ID' => 1234, // Node names will be 'Line' '<Lines' => [ ['item' => 'ABC', 'qty' => 3], ['item' => 'DEF', 'qty' => 1], ], // Node name will be 'Lines' // (some XSDs actually pluralize 'things' 🤦) '<Foo|Lines' => [ ['item' => 'ABC', 'qty' => 3], ['item' => 'DEF', 'qty' => 1], ], ], );
Yields:
<?xml version="1.0"?> <Order> <ID>1234</ID> <Line> <item>ABC</item> <qty>3</qty> </Line> <Line> <item>DEF</item> <qty>1</qty> </Line> <Lines> <item>ABC</item> <qty>3</qty> </Lines> <Lines> <item>DEF</item> <qty>1</qty> </Lines> </Order>
- Some parts are hard to model using arrays so you can "patch" with a
DOMDocument
$complex_dom = ...; ArrayToXML::toXML( 'Order' => [ 'ID' => 1234, '<complexdom' => $complexdom ], );
Yields:
<?xml version="1.0"?> <Order> <ID>1234</ID> <Line number="1"> <item>ABC</item> <qty>3</qty> </Line> <LineComment>Wrap well</LineComment> <Line number="2"> <item>DEF</item> <qty>1</qty> </Line> <LineComment/> </Order>
- Namespaces are just part of the name + an attribute on the root element.
ArrayToXML::toXML( 'Order@ns=...@ecom=...' => [ 'ns:ID' => 1234, '<ecom:Lines' => [ ['ecom:item' => 'ABC', 'ecom:qty' => 3], ['ecom:item' => 'DEF', 'ecom:qty' => 1], ] ], );
Yields:
<?xml version="1.0"?> <ns:Order ns="..." ecom="..."> <ns:ID>1234</ns:ID> <ecom:Line number="1"> <ecom:item>ABC</ecom:item> <ecom:qty>3</ecom:qty> </ecom:Line> <ecom:Line number="2"> <ecom:item>DEF</ecom:item> <ecom:qty>1</ecom:qty> </ecom:Line> </ns:Order>
- In cases you need a
DOMDocument
usetoDOM
ArrayToXML::toDOM( 'Order' => [ 'ID' => 1234, 'Lines' => [ ['item' => 'ABC', 'qty' => 3], ['item' => 'DEF', 'qty' => 1], ] ] );
- lets you set the version and encoding of the XML
ArrayToXML::toXML( 'Order' => [ 'ID' => 1234, 'Lines' => [ ['item' => 'ABC', 'qty' => 3], ['item' => 'DEF', 'qty' => 1], ] ], [ 'version' => '1.2', 'encoding' => 'utf8' ] );
Yields:
<?xml version="1.2" encoding="utf8"?> <Order> <ID>1234</ID> <Lines> <Line> <item>ABC</item> <qty>3</qty> </Line> <Line> <item>DEF</item> <qty>1</qty> </Line> </Lines> </Order>
- Setting
declare
to false will exclude the XML declaration at the top
ArrayToXML::toXML( 'Order' => [ 'ID' => 1234, 'Lines' => [ ['item' => 'ABC', 'qty' => 3], ['item' => 'DEF', 'qty' => 1], ] ], [ 'declare' => false ] );
Yields:
<Order> <ID>1234</ID> <Lines> <Line> <item>ABC</item> <qty>3</qty> </Line> <Line> <item>DEF</item> <qty>1</qty> </Line> </Lines> </Order>
- Conveniently create CDATA
ArrayToXML::toXML( 'Order' => [ 'ID' => 1234, 'Comment' => 'cdata:foo', ] );
Yields:
<?xml version="1.0"?> <Order> <ID>1234</ID> <Comment><![CDATA[foo]]></Comment> </Order>