Skip to content

Commit 58e3958

Browse files
committed
Init
0 parents  commit 58e3958

File tree

8 files changed

+426
-0
lines changed

8 files changed

+426
-0
lines changed

.github/workflows/main.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Integrity check
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
branches:
9+
- master
10+
11+
jobs:
12+
build:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- uses: actions/checkout@master
17+
18+
- name: Install PHP
19+
uses: shivammathur/setup-php@master
20+
with:
21+
php-version: 7.4
22+
23+
- name: Install composer deps
24+
run: |
25+
composer create-project nette/code-checker temp/code-checker ^3 --no-progress
26+
composer create-project nette/coding-standard temp/coding-standard ^2 --no-progress
27+
28+
# Install app deps
29+
composer install --no-interaction --prefer-dist
30+
31+
# Check code checker and coding standards
32+
- name: Check coding standards
33+
run: |
34+
php temp/code-checker/code-checker --short-arrays --strict-types --fix --no-progress
35+
php temp/coding-standard/ecs check src --config temp/coding-standard/coding-standard-php71.yml
36+
37+
- name: Check PHPStan rules
38+
run: composer phpstan
39+
40+
- name: Run tests
41+
run: tests/test.sh

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Baraja packages
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
XML to PHP array convertor
2+
==========================
3+
4+
Smart tool to convert your XML to PHP array.
5+
6+
This is fork from [gaarf/XML-string-to-PHP-array](https://github.com/gaarf/XML-string-to-PHP-array).
7+
8+
Install and simply use
9+
----------------------
10+
11+
Use Composer:
12+
13+
```shell
14+
composer require baraja-core/xml-to-php-array
15+
```
16+
17+
And then package will be automatically installed to your project and you can simply call:
18+
19+
```php
20+
$resultArray = Convertor::covertToArray($xml);
21+
```
22+
23+
Documentation
24+
-------------
25+
26+
One common need when working in PHP is a way to convert an XML document
27+
into a serializable array. If you ever tried to serialize() and then
28+
unserialize() a SimpleXML or DOMDocument object, you know what I’m
29+
talking about.
30+
31+
Assume the following XML snippet:
32+
33+
```xml
34+
<tv>
35+
<show name="Family Guy">
36+
<dog>Brian</dog>
37+
<kid>Chris</kid>
38+
<kid>Meg</kid>
39+
</show>
40+
</tv>
41+
```
42+
43+
There’s a quick and dirty way to do convert such a document to an array,
44+
using type casting and the JSON functions to ensure there are no exotic
45+
values that would cause problems when unserializing:
46+
47+
```php
48+
$a = json_decode(json_encode((array) Convertor::covertToArray($s)), true);
49+
```
50+
51+
Here is the result for our sample XML, eg if we `print_r($a)`:
52+
53+
```
54+
Array
55+
(
56+
[show] => Array
57+
(
58+
[@attributes] => Array
59+
(
60+
[name] => Family Guy
61+
)
62+
[dog] => Brian
63+
[kid] => Array
64+
(
65+
[0] => Chris
66+
[1] => Meg
67+
)
68+
)
69+
)
70+
```
71+
72+
Pretty nifty, eh? But maybe we want to embed some HTML tags or something
73+
crazy along those lines. then we need a CDATA node…
74+
75+
```xml
76+
<tv>
77+
<show name="Family Guy">
78+
<dog>Brian</dog>
79+
<kid>Chris</kid>
80+
<kid>Meg</kid>
81+
<kid><![CDATA[<em>Stewie</em>]]></kid>
82+
</show>
83+
</tv>
84+
```
85+
86+
The snippet of XML above would yield the following:
87+
88+
```
89+
Array
90+
(
91+
[show] => Array
92+
(
93+
[@attributes] => Array
94+
(
95+
[name] => Family Guy
96+
)
97+
[dog] => Brian
98+
[kid] => Array
99+
(
100+
[0] => Chris
101+
[1] => Meg
102+
[2] => Array
103+
(
104+
)
105+
)
106+
)
107+
)
108+
```
109+
110+
That’s not very useful. We got in trouble because the CDATA node, a
111+
SimpleXMLElement, is being cast to an array instead of a string. To
112+
handle this case while still keeping the nice @attributes notation, we
113+
need a slightly more verbose conversion function. This is my version,
114+
hereby released under a do-whatever-but-dont-sue-me license.
115+
116+
The result, for our *Stewie* snippet:
117+
118+
```
119+
Array
120+
(
121+
[show] => Array
122+
(
123+
[@attributes] => Array
124+
(
125+
[name] => Family Guy
126+
)
127+
[dog] => Brian
128+
[kid] => Array
129+
(
130+
[0] => Chris
131+
[1] => Meg
132+
[2] => <em>Stewie</em>
133+
)
134+
)
135+
)
136+
```
137+
138+
Victory is mine! :D

composer.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"name": "baraja-core/xml-to-php-array",
3+
"description": "XML to PHP array convertor",
4+
"homepage": "https://github.com/baraja-core/xml-to-array",
5+
"authors": [
6+
{
7+
"name": "Adrien Cahen",
8+
"homepage": "http://gaarf.info"
9+
},
10+
{
11+
"name": "Jan Barášek",
12+
"homepage": "https://baraja.cz"
13+
}
14+
],
15+
"require": {
16+
"php": ">=7.1.0",
17+
"ext-dom": "*"
18+
},
19+
"require-dev": {
20+
"phpstan/phpstan": "^0.12.18",
21+
"tracy/tracy": "^2.7",
22+
"phpstan/phpstan-nette": "^0.12.6"
23+
},
24+
"autoload": {
25+
"classmap": [
26+
"src/"
27+
]
28+
},
29+
"scripts": {
30+
"phpstan": [
31+
"vendor/bin/phpstan analyse src -c phpstan.neon --level 6 --no-progress"
32+
]
33+
},
34+
"minimum-stability": "stable"
35+
}

phpstan.neon

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
includes:
2+
- vendor/phpstan/phpstan-nette/extension.neon
3+
- vendor/phpstan/phpstan-nette/rules.neon

src/Convertor.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Baraja\XmlToPhp;
6+
7+
8+
final class Convertor
9+
{
10+
11+
/**
12+
* Convert xml string to php array - useful to get a serializable value.
13+
*
14+
* @return mixed[]
15+
*/
16+
public static function covertToArray(string $xml): array
17+
{
18+
assert(\class_exists('\DOMDocument'));
19+
$doc = new \DOMDocument();
20+
$doc->loadXML($xml);
21+
$root = $doc->documentElement;
22+
$output = (array) Helper::domNodeToArray($root);
23+
$output['@root'] = $root->tagName;
24+
25+
return $output ?? [];
26+
}
27+
}

src/Helper.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Baraja\XmlToPhp;
6+
7+
8+
final class Helper
9+
{
10+
11+
/** @throws \Error */
12+
public function __construct()
13+
{
14+
throw new \Error('Class ' . get_class($this) . ' is static and cannot be instantiated.');
15+
}
16+
17+
18+
/**
19+
* @param \DOMElement|\DOMNode $node
20+
* @return mixed[]|string
21+
*/
22+
public static function domNodeToArray($node)
23+
{
24+
$output = [];
25+
switch ($node->nodeType) {
26+
case 4: // XML_CDATA_SECTION_NODE
27+
case 3: // XML_TEXT_NODE
28+
$output = trim($node->textContent);
29+
break;
30+
case 1: // XML_ELEMENT_NODE
31+
for ($i = 0, $m = $node->childNodes->length; $i < $m; $i++) {
32+
$child = $node->childNodes->item($i);
33+
$v = self::domNodeToArray($child);
34+
if (isset($child->tagName)) {
35+
$t = $child->tagName;
36+
if (!isset($output[$t])) {
37+
$output[$t] = [];
38+
}
39+
if (is_array($v) && empty($v)) {
40+
$v = '';
41+
}
42+
$output[$t][] = $v;
43+
} elseif ($v || $v === '0') {
44+
$output = (string) $v;
45+
}
46+
}
47+
if ($node->attributes->length && !is_array($output)) { // has attributes but isn't an array
48+
$output = ['@content' => $output]; // change output into an array.
49+
}
50+
if (is_array($output)) {
51+
if ($node->attributes->length) {
52+
$a = [];
53+
foreach ($node->attributes as $attrName => $attrNode) {
54+
$a[$attrName] = (string) $attrNode->value;
55+
}
56+
$output['@attributes'] = $a;
57+
}
58+
foreach ($output as $t => $v) {
59+
if ($t !== '@attributes' && is_array($v) && count($v) === 1) {
60+
$output[$t] = $v[0];
61+
}
62+
}
63+
}
64+
break;
65+
}
66+
67+
return $output;
68+
}
69+
}

0 commit comments

Comments
 (0)