123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- <?php
- /**
- * Zend Framework (http://framework.zend.com/)
- *
- * @link http://github.com/zendframework/zf2 for the canonical source repository
- * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
- namespace Zend\Config\Reader;
- use XMLReader;
- use Zend\Config\Exception;
- /**
- * XML config reader.
- */
- class Xml implements ReaderInterface
- {
- /**
- * XML Reader instance.
- *
- * @var XMLReader
- */
- protected $reader;
- /**
- * Directory of the file to process.
- *
- * @var string
- */
- protected $directory;
- /**
- * Nodes to handle as plain text.
- *
- * @var array
- */
- protected $textNodes = array(
- XMLReader::TEXT,
- XMLReader::CDATA,
- XMLReader::WHITESPACE,
- XMLReader::SIGNIFICANT_WHITESPACE
- );
- /**
- * fromFile(): defined by Reader interface.
- *
- * @see ReaderInterface::fromFile()
- * @param string $filename
- * @return array
- * @throws Exception\RuntimeException
- */
- public function fromFile($filename)
- {
- if (!is_file($filename) || !is_readable($filename)) {
- throw new Exception\RuntimeException(sprintf(
- "File '%s' doesn't exist or not readable",
- $filename
- ));
- }
- $this->reader = new XMLReader();
- $this->reader->open($filename, null, LIBXML_XINCLUDE);
- $this->directory = dirname($filename);
- set_error_handler(
- function ($error, $message = '', $file = '', $line = 0) use ($filename) {
- throw new Exception\RuntimeException(sprintf(
- 'Error reading XML file "%s": %s',
- $filename, $message
- ), $error);
- }, E_WARNING
- );
- $return = $this->process();
- restore_error_handler();
- return $return;
- }
- /**
- * fromString(): defined by Reader interface.
- *
- * @see ReaderInterface::fromString()
- * @param string $string
- * @return array|bool
- * @throws Exception\RuntimeException
- */
- public function fromString($string)
- {
- if (empty($string)) {
- return array();
- }
- $this->reader = new XMLReader();
- $this->reader->xml($string, null, LIBXML_XINCLUDE);
- $this->directory = null;
- set_error_handler(
- function ($error, $message = '', $file = '', $line = 0) {
- throw new Exception\RuntimeException(sprintf(
- 'Error reading XML string: %s',
- $message
- ), $error);
- }, E_WARNING
- );
- $return = $this->process();
- restore_error_handler();
- return $return;
- }
- /**
- * Process data from the created XMLReader.
- *
- * @return array
- */
- protected function process()
- {
- return $this->processNextElement();
- }
- /**
- * Process the next inner element.
- *
- * @return mixed
- */
- protected function processNextElement()
- {
- $children = array();
- $text = '';
- while ($this->reader->read()) {
- if ($this->reader->nodeType === XMLReader::ELEMENT) {
- if ($this->reader->depth === 0) {
- return $this->processNextElement();
- }
- $attributes = $this->getAttributes();
- $name = $this->reader->name;
- if ($this->reader->isEmptyElement) {
- $child = array();
- } else {
- $child = $this->processNextElement();
- }
- if ($attributes) {
- if (!is_array($child)) {
- $child = array();
- }
- $child = array_merge($child, $attributes);
- }
- if (isset($children[$name])) {
- if (!is_array($children[$name]) || !array_key_exists(0, $children[$name])) {
- $children[$name] = array($children[$name]);
- }
- $children[$name][] = $child;
- } else {
- $children[$name] = $child;
- }
- } elseif ($this->reader->nodeType === XMLReader::END_ELEMENT) {
- break;
- } elseif (in_array($this->reader->nodeType, $this->textNodes)) {
- $text .= $this->reader->value;
- }
- }
- return $children ?: $text;
- }
- /**
- * Get all attributes on the current node.
- *
- * @return array
- */
- protected function getAttributes()
- {
- $attributes = array();
- if ($this->reader->hasAttributes) {
- while ($this->reader->moveToNextAttribute()) {
- $attributes[$this->reader->localName] = $this->reader->value;
- }
- $this->reader->moveToElement();
- }
- return $attributes;
- }
- }
|