Skip to content

Commit 6c09ccd

Browse files
committed
Create XML converter
1 parent 748d5f9 commit 6c09ccd

File tree

3 files changed

+210
-0
lines changed

3 files changed

+210
-0
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,12 @@ $converter->convert($storage->collectionName); // Returns the JSON but encodes n
160160
```
161161

162162
We use `JSON_PRETTY_PRINT` as default option.
163+
164+
### Xml
165+
166+
Converts data into XML format.
167+
168+
```php
169+
$converter = new Converter\Xml();
170+
$converter->convert($storage->collectionName); // Returns an string with the XML
171+
```

src/Converter/Xml.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
namespace PHPFluent\ArrayStorage\Converter;
4+
5+
use DOMDocument;
6+
use DOMElement;
7+
use ReflectionObject;
8+
use stdClass;
9+
use Traversable;
10+
11+
class Xml implements Converter
12+
{
13+
protected $document;
14+
15+
public function __construct(DOMDocument $document = null)
16+
{
17+
if (null === $document) {
18+
$document = new DOMDocument('1.0', 'UTF-8');
19+
$document->formatOutput = true;
20+
}
21+
22+
$this->document = $document;
23+
}
24+
25+
protected function getNodeName($value)
26+
{
27+
if (is_object($value)) {
28+
return (new ReflectionObject($value))->getShortName();
29+
}
30+
31+
return 'value';
32+
}
33+
34+
protected function parseNode($traversable, DOMElement $parentNode)
35+
{
36+
foreach ($traversable as $key => $value) {
37+
$nodeName = is_int($key) ? $this->getNodeName($value) : $key;
38+
$childNode = $this->document->createElement($nodeName);
39+
$parentNode->appendChild($childNode);
40+
if ($value instanceof Traversable
41+
|| $value instanceof stdClass
42+
|| is_array($value)) {
43+
$this->parseNode($value, $childNode);
44+
continue;
45+
}
46+
$childNode->nodeValue = $value;
47+
}
48+
}
49+
50+
public function convert(Traversable $traversable)
51+
{
52+
$name = $this->getNodeName($traversable);
53+
$childNode = $this->document->createElement($name);
54+
$this->document->appendChild($childNode);
55+
$this->parseNode($traversable, $childNode);
56+
57+
return $this->document->saveXml();
58+
}
59+
}

tests/Converter/XmlTest.php

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<?php
2+
3+
namespace PHPFluent\ArrayStorage\Converter;
4+
5+
use DOMDocument;
6+
use PHPFluent\ArrayStorage\Factory;
7+
use PHPFluent\ArrayStorage\Storage;
8+
use stdClass;
9+
10+
/**
11+
* @covers PHPFluent\ArrayStorage\Converter\Xml
12+
*/
13+
class XmlTest extends \PHPUnit_Framework_TestCase
14+
{
15+
protected $factory;
16+
17+
protected function setUp()
18+
{
19+
$this->factory = new Factory();
20+
}
21+
22+
public function testShouldAcceptAnInstanceOfDOMDocumentOnConstructor()
23+
{
24+
$document = new DOMDocument();
25+
$converter = new Xml($document);
26+
27+
$this->assertAttributeSame($document, 'document', $converter);
28+
}
29+
30+
public function testShouldHaveAConfiguredInstanceOfDOMDocumentByDefault()
31+
{
32+
$converter = new Xml();
33+
34+
$this->assertAttributeInstanceOf('DOMDocument', 'document', $converter);
35+
}
36+
37+
public function testShouldConvertRecord()
38+
{
39+
$converter = new Xml();
40+
41+
$record = $this->factory->record();
42+
$record->id = 10;
43+
$record->name = 'Henrique Moody';
44+
$record->child = $this->factory->record(array('id' => 10));
45+
$record->ids = array(1, 2, 'keyName' => 3);
46+
$record->other = new stdClass();
47+
$record->other->foo = true;
48+
$record->other->bar = 'Some';
49+
50+
$expectedValue = <<<XML
51+
<?xml version="1.0" encoding="UTF-8"?>
52+
<Record>
53+
<id>10</id>
54+
<name>Henrique Moody</name>
55+
<child>
56+
<id>10</id>
57+
</child>
58+
<ids>
59+
<value>1</value>
60+
<value>2</value>
61+
<keyName>3</keyName>
62+
</ids>
63+
<other>
64+
<foo>1</foo>
65+
<bar>Some</bar>
66+
</other>
67+
</Record>
68+
69+
XML;
70+
$actualValue = $converter->convert($record);
71+
72+
$this->assertSame($expectedValue, $actualValue);
73+
}
74+
75+
public function testShouldConvertCollection()
76+
{
77+
$converter = new Xml();
78+
79+
$record1 = $this->factory->record();
80+
$record2 = $this->factory->record();
81+
$record3 = $this->factory->record();
82+
83+
$collection = $this->factory->collection();
84+
$collection->insert($record1);
85+
$collection->insert($record2);
86+
$collection->insert($record3);
87+
88+
$expectedValue = <<<XML
89+
<?xml version="1.0" encoding="UTF-8"?>
90+
<Collection>
91+
<Record>
92+
<id>1</id>
93+
</Record>
94+
<Record>
95+
<id>2</id>
96+
</Record>
97+
<Record>
98+
<id>3</id>
99+
</Record>
100+
</Collection>
101+
102+
XML;
103+
$actualValue = $converter->convert($collection);
104+
105+
$this->assertSame($expectedValue, $actualValue);
106+
}
107+
108+
public function testShouldConvertStorage()
109+
{
110+
$converter = new Xml();
111+
112+
$record1 = $this->factory->record();
113+
$record2 = $this->factory->record();
114+
$record3 = $this->factory->record();
115+
116+
$storage = new Storage($this->factory);
117+
$storage->whatever->insert($record1);
118+
$storage->whatever->insert($record2);
119+
$storage->whatever->insert($record3);
120+
121+
$expectedValue = <<<XML
122+
<?xml version="1.0" encoding="UTF-8"?>
123+
<Storage>
124+
<whatever>
125+
<Record>
126+
<id>1</id>
127+
</Record>
128+
<Record>
129+
<id>2</id>
130+
</Record>
131+
<Record>
132+
<id>3</id>
133+
</Record>
134+
</whatever>
135+
</Storage>
136+
137+
XML;
138+
$actualValue = $converter->convert($storage);
139+
140+
$this->assertSame($expectedValue, $actualValue);
141+
}
142+
}

0 commit comments

Comments
 (0)