Skip to content

Commit 4b13fe2

Browse files
committed
added Xml helper
0 parents  commit 4b13fe2

File tree

6 files changed

+386
-0
lines changed

6 files changed

+386
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
vendor

composer.json

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "darkfriend/php5-xml",
3+
"type": "library",
4+
"description": "PHP5 scripts helper for xml",
5+
"keywords": ["dev","xml","helper","darkfriend","development","php5","php"],
6+
"homepage": "https://github.com/darkfriend/php5-xml",
7+
"authors": [
8+
{
9+
"name": "darkfriend",
10+
"email": "hi@darkfriend.ru"
11+
}
12+
],
13+
"require": {
14+
"php":">=5.3"
15+
},
16+
"autoload": {
17+
"psr-4": {
18+
"darkfriend\\helpers\\": "src/"
19+
}
20+
}
21+
}

readme.md

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# PHP5 XML helper
2+
3+
* Array to XML (``` XML::encode() ```)
4+
* XML to Array (``` XML::decode() ```)
5+
6+
## How to use
7+
8+
### Array to XML (encode)
9+
10+
```php
11+
$array = array(
12+
'bar' => 'value bar',
13+
'foo' => 'value foo',
14+
'der' => array(
15+
'@cdata' => 'this is long text',
16+
'@attributes' => array(
17+
'at1' => 'at1val',
18+
'at2' => 'at2val',
19+
),
20+
),
21+
'qpo' => array(
22+
'sub1' => array('sub2'=>'val')
23+
)
24+
);
25+
26+
echo \darkfriend\helpers\Xml::encode($array);
27+
```
28+
29+
#### Result encode
30+
31+
```xml
32+
<root>
33+
<bar>value bar</bar>
34+
<foo>value foo</foo>
35+
<der at1="at1val" at2="at2val"><![CDATA[this is long text]]></der>
36+
<qpo>
37+
<sub1>
38+
<sub2>val</sub2>
39+
</sub1>
40+
</qpo>
41+
</root>
42+
```
43+
44+
### Xml string to Array (decode)
45+
46+
```php
47+
$xml = '<?xml version="1.0"?>
48+
<root>
49+
<bar>value bar</bar>
50+
<foo>value foo</foo>
51+
<der at1="at1val" at2="at2val"><![CDATA[this is long text]]></der>
52+
<qpo>
53+
<sub1>
54+
<sub2>val</sub2>
55+
</sub1>
56+
</qpo>
57+
</root>
58+
';
59+
60+
var_dump(\darkfriend\helpers\Xml::decode($xml));
61+
```
62+
63+
#### Result decode
64+
65+
```
66+
Array
67+
(
68+
[bar] => value bar
69+
[foo] => value foo
70+
[der] => Array
71+
(
72+
[@attributes] => Array
73+
(
74+
[at1] => at1val
75+
[at2] => at2val
76+
)
77+
[@value] => this is long text
78+
)
79+
[qpo] => Array
80+
(
81+
[sub1] => Array
82+
(
83+
[sub2] => val
84+
)
85+
)
86+
)
87+
```

src/SimpleXMLElement.php

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace darkfriend\helpers;
4+
5+
/**
6+
* Class SimpleXMLElement
7+
* @package darkfriend\helpers
8+
* @author darkfriend <hi@darkfriend.ru>
9+
* @version 1.0.0
10+
*/
11+
class SimpleXMLElement extends \SimpleXMLElement
12+
{
13+
public function addCData($cdata_text)
14+
{
15+
$node = \dom_import_simplexml($this);
16+
$no = $node->ownerDocument;
17+
$node->appendChild($no->createCDATASection($cdata_text));
18+
}
19+
}

src/Xml.php

+228
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
<?php
2+
3+
namespace darkfriend\helpers;
4+
5+
/**
6+
* Class Xml
7+
* @package darkfriend\helpers
8+
* @author darkfriend <hi@darkfriend.ru>
9+
* @version 1.0.0
10+
*/
11+
class Xml
12+
{
13+
protected static $root = '<root/>';
14+
15+
/**
16+
* Convert array to xml
17+
* @param mixed $data
18+
* @param array $params = [
19+
* 'root' => '<root/>',
20+
* 'exception' => false,
21+
* ]
22+
* @return string
23+
* @throws XmlException
24+
*/
25+
public static function encode($data, $params = array())
26+
{
27+
\libxml_use_internal_errors(true);
28+
29+
if(empty($params['root'])) {
30+
$params['root'] = self::$root;
31+
}
32+
33+
$xml = new SimpleXMLElement($params['root']);
34+
$xml = self::generateXml($xml, $data);
35+
36+
if(!static::checkException($params)) {
37+
return '';
38+
}
39+
40+
return $xml->asXML();
41+
}
42+
43+
/**
44+
* @param SimpleXMLElement $xml
45+
* @param mixed $data
46+
* @return SimpleXMLElement
47+
*/
48+
public static function generateXml($xml, $data)
49+
{
50+
/** @var $xml SimpleXMLElement */
51+
if(is_array($data)) {
52+
foreach ($data as $key=>$item) {
53+
self::addChild($xml,$key,$item);
54+
}
55+
} else {
56+
self::addChild($xml,$data);
57+
}
58+
return $xml;
59+
}
60+
61+
/**
62+
* Add child
63+
* @param SimpleXMLElement $xml
64+
* @param string $name
65+
* @param array|string $params
66+
* @return SimpleXMLElement
67+
*/
68+
public static function addChild($xml, $name, $params = '')
69+
{
70+
if(is_array($params)) {
71+
$value = null;
72+
if(key_exists('@value',$params)) {
73+
$value = $params['@value'];
74+
unset($params['@value']);
75+
}
76+
77+
$namespace = null;
78+
if(key_exists('@namespace',$params)) {
79+
$namespace = $params['@namespace'];
80+
unset($params['@namespace']);
81+
}
82+
83+
$child = $xml->addChild($name,$value, $namespace);
84+
85+
if(key_exists('@attributes',$params)) {
86+
foreach ($params['@attributes'] as $keyAttr=>$attr) {
87+
$child->addAttribute($keyAttr, $attr);
88+
}
89+
unset($params['@attributes']);
90+
}
91+
92+
if(key_exists('@cdata',$params)) {
93+
$child->addCData($params['@cdata']);
94+
unset($params['@cdata']);
95+
}
96+
97+
foreach ($params as $key => $item) {
98+
if(is_array($item)) {
99+
self::addChild($child,$key,$item);
100+
} else {
101+
$child->addChild($key,$item);
102+
}
103+
}
104+
} else {
105+
$child = $xml->addChild($name, $params);
106+
}
107+
108+
return $child;
109+
}
110+
111+
/**
112+
* Decode XML string
113+
* @param string $data
114+
* @param array $params = [
115+
* 'convert' => true,
116+
* 'exception' => false,
117+
* ]
118+
* @return \darkfriend\helpers\SimpleXMLElement|array
119+
* @throws XmlException
120+
*/
121+
public static function decode($data, $params = array())
122+
{
123+
\libxml_use_internal_errors(true);
124+
125+
$xml = \simplexml_load_string(
126+
$data,
127+
'\darkfriend\helpers\SimpleXMLElement',
128+
\LIBXML_NOCDATA
129+
);
130+
131+
if(!static::checkException($params)) {
132+
return array();
133+
}
134+
135+
if(!isset($params['convert'])) {
136+
$params['convert'] = true;
137+
}
138+
139+
if($params['convert']) {
140+
return self::convertSimpleXml($xml);
141+
} else {
142+
return $xml;
143+
}
144+
}
145+
146+
/**
147+
* Convert tree SimpleXMLElement
148+
* @param SimpleXMLElement $xml
149+
* @return array
150+
*/
151+
public static function convertSimpleXml($xml)
152+
{
153+
$res = array();
154+
/** @var SimpleXMLElement $item */
155+
foreach ($xml as $key=>$item) {
156+
if($item->count()>0) {
157+
$res[$key] = self::convertSimpleXml($item);
158+
} else {
159+
$res[$key] = self::convertSimpleXmlItem($item);
160+
}
161+
}
162+
return $res;
163+
}
164+
165+
/**
166+
* Convert item SimpleXMLElement
167+
* @param SimpleXMLElement $item
168+
* @return array|string
169+
*/
170+
public static function convertSimpleXmlItem($item)
171+
{
172+
/** @var SimpleXMLElement $item */
173+
$attr = $item->attributes();
174+
if(!empty($attr)) {
175+
$element = (array) $attr;
176+
$element['@value'] = (string) $item;
177+
} else {
178+
$element = (string) $item;
179+
}
180+
return $element;
181+
}
182+
183+
/**
184+
* Check error
185+
* @param array $params = [
186+
* 'exception' => true,
187+
* ]
188+
* @return bool if $params['exception'] === false
189+
* @throws XmlException if $params['exception'] === true
190+
*/
191+
public static function checkException($params = array())
192+
{
193+
$e = \libxml_get_errors();
194+
195+
if(!$e) {
196+
return true;
197+
}
198+
199+
$strError = '';
200+
foreach($e as $key => $xmlError) {
201+
$strError .= "$key:".$xmlError->message . "\n";
202+
}
203+
204+
if($params['exception']) {
205+
throw new XmlException("XML error: $strError", 100, __FILE__, __LINE__);
206+
}
207+
208+
return true;
209+
}
210+
211+
/**
212+
* Set root element
213+
* @param string $root
214+
*/
215+
public static function setRootElement($root = '<root/>')
216+
{
217+
self::$root = $root;
218+
}
219+
220+
/**
221+
* Get root element
222+
* @return string
223+
*/
224+
public static function getRootElement()
225+
{
226+
return self::$root;
227+
}
228+
}

src/XmlException.php

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace darkfriend\helpers;
4+
5+
/**
6+
* Class XmlException
7+
* @package darkfriend\helpers
8+
* @author darkfriend <hi@darkfriend.ru>
9+
* @version 1.0.0
10+
*/
11+
class XmlException extends \Exception
12+
{
13+
/**
14+
* Creates new exception object.
15+
* @param string $message
16+
* @param int $code
17+
* @param string $file
18+
* @param int $line
19+
* @param \Exception $previous
20+
*/
21+
public function __construct($message = "", $code = 0, $file = "", $line = 0, \Exception $previous = null)
22+
{
23+
parent::__construct($message, $code, $previous);
24+
25+
if (!empty($file) && !empty($line)) {
26+
$this->file = $file;
27+
$this->line = $line;
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)