-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Anton Trofimenko
committed
Sep 20, 2015
1 parent
450ce4e
commit 3614973
Showing
5 changed files
with
298 additions
and
147 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,11 @@ | ||
# Changelog | ||
|
||
## v1.4 | ||
|
||
### Change | ||
|
||
Renaming again and again. | ||
|
||
## v1.3 | ||
|
||
### Change | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,144 @@ | ||
# XML to Array PHP | ||
============== | ||
XML to Array | ||
=========== | ||
|
||
## Convert XML to PHP Array | ||
## Convert XML to Array | ||
|
||
This class can parse XML and return the document structure in an array. | ||
It takes a string with a XML document and parses it using PHP SimpleXML or Expat extensions. | ||
The class returns an nested array with the details of each XML document tag and data elements. | ||
The class returns an nested array with the details of each XML document tag and data elements. | ||
|
||
## Examples | ||
|
||
#### Simple XML without attributes | ||
|
||
```xml | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<data> | ||
<extra1>1111</extra1> | ||
<extra2>2222</extra2> | ||
<extra3>3333</extra3> | ||
</data> | ||
``` | ||
|
||
```php | ||
XmlToArray::xmlToArray($xml); | ||
|
||
array( | ||
'data' => array( | ||
'extra1' => 1111, | ||
'extra2' => 2222, | ||
'extra3' => 3333, | ||
), | ||
) | ||
``` | ||
|
||
#### More complex XML | ||
|
||
```xml | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<data> | ||
<id>1001</id> | ||
<info att1="one" att2="two"></info> | ||
<extra>1111</extra> | ||
<extra>2222</extra> | ||
<extra>3333</extra> | ||
</data> | ||
``` | ||
|
||
#### More informative array | ||
|
||
```php | ||
XmlToArray::xmlToArray($xml); | ||
|
||
array( | ||
'data' => array( | ||
'id' => 1001, | ||
'info' => null, | ||
'@info' => array( | ||
'att1' => 'one', | ||
'att2' => 'two', | ||
), | ||
'extra' => array( | ||
0 => 1111, | ||
1 => 2222, | ||
2 => 3333, | ||
), | ||
), | ||
) | ||
``` | ||
|
||
#### Attributes is priority | ||
|
||
```php | ||
XmlToArray::xmlToArray($xml, true, false); | ||
|
||
array( | ||
'data' => array( | ||
'id' => array( | ||
'value' => 1001, | ||
), | ||
'info' => array( | ||
'@attributes' => array( | ||
'att1' => 'one', | ||
'att2' => 'two', | ||
), | ||
), | ||
'extra' => array( | ||
0 => array( | ||
'value' => 1111, | ||
), | ||
1 => array( | ||
'value' => 2222, | ||
), | ||
2 => array( | ||
'value' => 3333, | ||
), | ||
), | ||
), | ||
) | ||
``` | ||
|
||
#### Attributes can be omitted | ||
|
||
```php | ||
XmlToArray::xmlToArray($xml, false, true); | ||
|
||
array( | ||
'data' => array( | ||
'id' => 1001, | ||
'info' => null, | ||
'extra' => array( | ||
0 => 1111, | ||
1 => 2222, | ||
2 => 3333, | ||
), | ||
), | ||
) | ||
``` | ||
|
||
#### Attributes will be omitted and tags will fulfill role of attributes | ||
|
||
```php | ||
XmlToArray::xmlToArray($xml, false, false); | ||
|
||
array( | ||
'data' => array( | ||
'id' => array( | ||
'value' => 1001, | ||
), | ||
'info' => null, | ||
'extra' => array( | ||
0 => array( | ||
'value' => 1111, | ||
), | ||
1 => array( | ||
'value' => 2222, | ||
), | ||
2 => array( | ||
'value' => 3333, | ||
), | ||
), | ||
), | ||
) | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
<?php | ||
namespace p54l0m5h1k\XmlToArray; | ||
|
||
/** | ||
* An easy way to convert xml to php array. | ||
* | ||
* @link https://github.com/P54l0m5h1k/XML-to-Array-PHP/ | ||
* @link https://github.com/P54l0m5h1k/Array-to-XML-PHP/ | ||
*/ | ||
class XmlToArray | ||
{ | ||
/** | ||
* Parsing XML into array. | ||
* | ||
* @static | ||
* | ||
* @param string $contents string containing XML | ||
* @param bool $getAttributes | ||
* @param bool $tagPriority priority of values in the array - `true` if the higher priority in the tag, | ||
* `false` if only the attributes needed | ||
* @param string $encoding target XML encoding | ||
* | ||
* @return array | ||
*/ | ||
public static function xmlToArray($contents, $getAttributes = true, $tagPriority = true, $encoding = 'utf-8') | ||
{ | ||
$contents = trim($contents); | ||
if (empty($contents)) { | ||
return []; | ||
} | ||
$parser = xml_parser_create(''); | ||
xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $encoding); | ||
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); | ||
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); | ||
if (xml_parse_into_struct($parser, $contents, $xmlValues) === 0) { | ||
xml_parser_free($parser); | ||
|
||
return []; | ||
} | ||
xml_parser_free($parser); | ||
if (empty($xmlValues)) { | ||
return []; | ||
} | ||
unset($contents, $parser); | ||
$xmlArray = []; | ||
$current = &$xmlArray; | ||
$repeatedTagIndex = []; | ||
foreach ($xmlValues as $num => $xmlTag) { | ||
$result = null; | ||
$attributesData = null; | ||
if (isset($xmlTag['value'])) { | ||
if ($tagPriority) { | ||
$result = $xmlTag['value']; | ||
} else { | ||
$result['value'] = $xmlTag['value']; | ||
} | ||
} | ||
if (isset($xmlTag['attributes']) and $getAttributes) { | ||
foreach ($xmlTag['attributes'] as $attr => $val) { | ||
if ($tagPriority) { | ||
$attributesData[$attr] = $val; | ||
} else { | ||
$result['@attributes'][$attr] = $val; | ||
} | ||
} | ||
} | ||
if ($xmlTag['type'] == 'open') { | ||
$parent[$xmlTag['level'] - 1] = &$current; | ||
if (!is_array($current) or (!in_array($xmlTag['tag'], array_keys($current)))) { | ||
$current[$xmlTag['tag']] = $result; | ||
unset($result); | ||
if ($attributesData) { | ||
$current['@'.$xmlTag['tag']] = $attributesData; | ||
} | ||
$repeatedTagIndex[$xmlTag['tag'].'_'.$xmlTag['level']] = 1; | ||
$current = &$current[$xmlTag['tag']]; | ||
} else { | ||
if (isset($current[$xmlTag['tag']]['0'])) { | ||
$current[$xmlTag['tag']][$repeatedTagIndex[$xmlTag['tag'].'_'.$xmlTag['level']]] = $result; | ||
unset($result); | ||
if ($attributesData) { | ||
if (isset($repeatedTagIndex['@'.$xmlTag['tag'].'_'.$xmlTag['level']])) { | ||
$current[$xmlTag['tag']][$repeatedTagIndex['@'.$xmlTag['tag'].'_'.$xmlTag['level']]] = $attributesData; | ||
} | ||
} | ||
$repeatedTagIndex[$xmlTag['tag'].'_'.$xmlTag['level']] += 1; | ||
} else { | ||
$current[$xmlTag['tag']] = [$current[$xmlTag['tag']], $result]; | ||
unset($result); | ||
$repeatedTagIndex[$xmlTag['tag'].'_'.$xmlTag['level']] = 2; | ||
if (isset($current['@'.$xmlTag['tag']])) { | ||
$current[$xmlTag['tag']]['@0'] = $current['@'.$xmlTag['tag']]; | ||
unset($current['@'.$xmlTag['tag']]); | ||
} | ||
if ($attributesData) { | ||
$current[$xmlTag['tag']]['@1'] = $attributesData; | ||
} | ||
} | ||
$lastItemIndex = $repeatedTagIndex[$xmlTag['tag'].'_'.$xmlTag['level']] - 1; | ||
$current = &$current[$xmlTag['tag']][$lastItemIndex]; | ||
} | ||
} elseif ($xmlTag['type'] == 'complete') { | ||
if (!isset($current[$xmlTag['tag']]) and empty($current['@'.$xmlTag['tag']])) { | ||
$current[$xmlTag['tag']] = $result; | ||
unset($result); | ||
$repeatedTagIndex[$xmlTag['tag'].'_'.$xmlTag['level']] = 1; | ||
if ($tagPriority and $attributesData) { | ||
$current['@'.$xmlTag['tag']] = $attributesData; | ||
} | ||
} else { | ||
if (isset($current[$xmlTag['tag']]['0']) and is_array($current[$xmlTag['tag']])) { | ||
$current[$xmlTag['tag']][$repeatedTagIndex[$xmlTag['tag'].'_'.$xmlTag['level']]] = $result; | ||
unset($result); | ||
if ($tagPriority and $getAttributes and $attributesData) { | ||
$current[$xmlTag['tag']]['@'.$repeatedTagIndex[$xmlTag['tag'].'_'.$xmlTag['level']]] = $attributesData; | ||
} | ||
$repeatedTagIndex[$xmlTag['tag'].'_'.$xmlTag['level']] += 1; | ||
} else { | ||
$current[$xmlTag['tag']] = [ | ||
$current[$xmlTag['tag']], | ||
$result, | ||
]; | ||
unset($result); | ||
$repeatedTagIndex[$xmlTag['tag'].'_'.$xmlTag['level']] = 1; | ||
if ($tagPriority and $getAttributes) { | ||
if (isset($current['@'.$xmlTag['tag']])) { | ||
$current[$xmlTag['tag']]['@0'] = $current['@'.$xmlTag['tag']]; | ||
unset($current['@'.$xmlTag['tag']]); | ||
} | ||
if ($attributesData) { | ||
$current[$xmlTag['tag']]['@'.$repeatedTagIndex[$xmlTag['tag'].'_'.$xmlTag['level']]] = $attributesData; | ||
} | ||
} | ||
$repeatedTagIndex[$xmlTag['tag'].'_'.$xmlTag['level']] += 1; | ||
} | ||
} | ||
} elseif ($xmlTag['type'] == 'close') { | ||
$current = &$parent[$xmlTag['level'] - 1]; | ||
} | ||
unset($xmlValues[$num]); | ||
} | ||
|
||
return $xmlArray; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.