Skip to content

Commit

Permalink
first version
Browse files Browse the repository at this point in the history
  • Loading branch information
rez1dent3 committed May 4, 2017
1 parent 2b3578d commit e74f37a
Show file tree
Hide file tree
Showing 5 changed files with 268 additions and 4 deletions.
6 changes: 2 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
composer.phar
/vendor/

# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
# composer.lock
composer.lock
.idea
21 changes: 21 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "bavix/xml",
"description": "XML Reader",
"minimum-stability": "stable",
"license": "MIT",
"authors": [
{
"name": "Babichev Maxim",
"email": "[email protected]"
}
],
"require": {
"bavix/foundation": "^1.0",
"bavix/exceptions": "^1.0"
},
"autoload": {
"psr-4": {
"Bavix\\": "src/"
}
}
}
15 changes: 15 additions & 0 deletions demo/c.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<root>
<lang name="C">
<appeared>1972</appeared>
<creator>Dennis Ritchie</creator>
</lang>
<lang name="PHP">
<appeared>1995</appeared>
<creator>Rasmus Lerdorf</creator>
</lang>
<lang name="Java">
<appeared>1995</appeared>
<creator>James Gosling</creator>
</lang>
</root>
9 changes: 9 additions & 0 deletions demo/reader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

include_once dirname(__DIR__) . '/vendor/autoload.php';

$reader = \Bavix\XMLReader\XMLReader::sharedInstance();

$data = $reader->asArray('c.xml');

var_dump($reader->asXML($data));
221 changes: 221 additions & 0 deletions src/XMLReader/XMLReader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
<?php

namespace Bavix\XMLReader;

use Bavix\Exceptions;
use Bavix\Foundation\SharedInstance;
use DOMElement;

class XMLReader
{

use SharedInstance;

/**
* @var array
*/
protected $copyright = ['created-with' => 'https://github.com/bavix/xml'];

/**
* @var \DOMDocument
*/
protected $document;

/**
* @return \DOMDocument
*/
protected function document()
{
if (!$this->document)
{
$this->document = new \DOMDocument('1.0', 'utf-8');
$this->document->formatOutput = true;
$this->copyright['created-at'] = date('Y-m-d H:i:s');
}

return $this->document;
}

/**
* @param string $name
*
* @return \DOMElement
*/
protected function element($name)
{
return $this->document()->createElement($name);
}

/**
* @param string $file
*
* @return array
*/
public function asArray($file)
{
$reader = \simplexml_load_file($file);

return json_decode(json_encode((array)$reader), true);
}

/**
* @param array $storage
*
* @return string
*/
public function asXML(array $storage)
{
$element = $this->element('bavix');

$this->addAttributes($element, $this->copyright);
$this->document()->appendChild($element);
$this->convert($element, $storage);
$xml = $this->document()->saveXML();

$this->document = null;

return $xml;
}

/**
* @param DOMElement $element
* @param mixed $storage
*
* @throws Exceptions\Blank
*/
protected function convert(DOMElement $element, $storage)
{
if (!is_array($storage))
{
$element->nodeValue = htmlspecialchars($storage);

return;
}

if (count($storage) === 0)
{
throw new Exceptions\Blank('Array is empty');
}

$isInt = array_map('is_int', array_keys($storage));
$sequential = !in_array(false, $isInt, true);

foreach ($storage as $key => $data)
{
if ($sequential)
{
$this->sequential($element, $data);
continue;
}

$this->addNodeWithKey($key, $element, $data);
}
}

/**
* @param string $key
* @param DOMElement $element
* @param mixed $storage
*/
protected function addNodeWithKey($key, DOMElement $element, $storage)
{
if ($key === '@attributes')
{
$this->addAttributes($element, $storage);
}
elseif ($key === '@value' && is_string($storage))
{
$element->nodeValue = htmlspecialchars($storage);
}
else
{
$this->addNode($element, $key, $storage);
}
}

/**
* @param DOMElement $element
* @param mixed $storage
*/
protected function sequential(DOMElement $element, $storage)
{
if (is_array($storage))
{
$this->addCollectionNode($element, $storage);
}
else
{

$this->addSequentialNode($element, $storage);
}
}

/**
* @param DOMElement $element
* @param string $key
* @param mixed $value
*
* @throws Exceptions\Blank
*/
protected function addNode(DOMElement $element, $key, $value)
{
$key = str_replace(' ', '_', $key);
$child = $this->document()->createElement($key);
$element->appendChild($child);
$this->convert($child, $value);
}

/**
* @param DOMElement $element
* @param mixed $value
*
* @throws Exceptions\Blank
*/
protected function addCollectionNode(DOMElement $element, $value)
{
if ($element->childNodes->length === 0)
{
$this->convert($element, $value);

return;
}

/**
* @var $child DOMElement
*/
$child = $element->cloneNode();
$element->parentNode->appendChild($child);
$this->convert($child, $value);
}

/**
* @param DOMElement $element
* @param mixed $value
*/
protected function addSequentialNode(DOMElement $element, $value)
{
if (empty($element->nodeValue))
{
$element->nodeValue = htmlspecialchars($value);

return;
}

$child = $element->cloneNode();
$child->nodeValue = htmlspecialchars($value);
$element->parentNode->appendChild($child);
}

/**
* @param DOMElement $element
* @param array $storage
*/
protected function addAttributes(DOMElement $element, array $storage)
{
foreach ($storage as $attrKey => $attrVal)
{
$element->setAttribute($attrKey, $attrVal);
}
}

}

0 comments on commit e74f37a

Please sign in to comment.