3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
10 namespace Zend\Config\Reader
;
13 use Zend\Config\Exception
;
18 class Xml
implements ReaderInterface
21 * XML Reader instance.
28 * Directory of the file to process.
35 * Nodes to handle as plain text.
39 protected $textNodes = array(
42 XMLReader
::WHITESPACE
,
43 XMLReader
::SIGNIFICANT_WHITESPACE
47 * fromFile(): defined by Reader interface.
49 * @see ReaderInterface::fromFile()
50 * @param string $filename
52 * @throws Exception\RuntimeException
54 public function fromFile($filename)
56 if (!is_file($filename) ||
!is_readable($filename)) {
57 throw new Exception\
RuntimeException(sprintf(
58 "File '%s' doesn't exist or not readable",
63 $this->reader
= new XMLReader();
64 $this->reader
->open($filename, null, LIBXML_XINCLUDE
);
66 $this->directory
= dirname($filename);
69 function ($error, $message = '', $file = '', $line = 0) use ($filename) {
70 throw new Exception\
RuntimeException(sprintf(
71 'Error reading XML file "%s": %s',
76 $return = $this->process();
77 restore_error_handler();
83 * fromString(): defined by Reader interface.
85 * @see ReaderInterface::fromString()
86 * @param string $string
88 * @throws Exception\RuntimeException
90 public function fromString($string)
95 $this->reader
= new XMLReader();
97 $this->reader
->xml($string, null, LIBXML_XINCLUDE
);
99 $this->directory
= null;
102 function ($error, $message = '', $file = '', $line = 0) {
103 throw new Exception\
RuntimeException(sprintf(
104 'Error reading XML string: %s',
109 $return = $this->process();
110 restore_error_handler();
116 * Process data from the created XMLReader.
120 protected function process()
122 return $this->processNextElement();
126 * Process the next inner element.
130 protected function processNextElement()
135 while ($this->reader
->read()) {
136 if ($this->reader
->nodeType
=== XMLReader
::ELEMENT
) {
137 if ($this->reader
->depth
=== 0) {
138 return $this->processNextElement();
141 $attributes = $this->getAttributes();
142 $name = $this->reader
->name
;
144 if ($this->reader
->isEmptyElement
) {
147 $child = $this->processNextElement();
151 if (!is_array($child)) {
155 $child = array_merge($child, $attributes);
158 if (isset($children[$name])) {
159 if (!is_array($children[$name]) ||
!array_key_exists(0, $children[$name])) {
160 $children[$name] = array($children[$name]);
163 $children[$name][] = $child;
165 $children[$name] = $child;
167 } elseif ($this->reader
->nodeType
=== XMLReader
::END_ELEMENT
) {
169 } elseif (in_array($this->reader
->nodeType
, $this->textNodes
)) {
170 $text .= $this->reader
->value
;
174 return $children ?
: $text;
178 * Get all attributes on the current node.
182 protected function getAttributes()
184 $attributes = array();
186 if ($this->reader
->hasAttributes
) {
187 while ($this->reader
->moveToNextAttribute()) {
188 $attributes[$this->reader
->localName
] = $this->reader
->value
;
191 $this->reader
->moveToElement();