ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Reader.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Sabre\Xml;
4 
5 use XMLReader;
6 
20 class Reader extends XMLReader {
21 
23 
34  function getClark() {
35 
36  if (! $this->localName) {
37  return null;
38  }
39 
40  return '{' . $this->namespaceURI . '}' . $this->localName;
41 
42  }
43 
57  function parse() {
58 
59  $previousEntityState = libxml_disable_entity_loader(true);
60  $previousSetting = libxml_use_internal_errors(true);
61 
62  try {
63 
64  // Really sorry about the silence operator, seems like I have no
65  // choice. See:
66  //
67  // https://bugs.php.net/bug.php?id=64230
68  while ($this->nodeType !== self::ELEMENT && @$this->read()) {
69  // noop
70  }
71  $result = $this->parseCurrentElement();
72 
73  $errors = libxml_get_errors();
74  libxml_clear_errors();
75  if ($errors) {
76  throw new LibXMLException($errors);
77  }
78 
79  } finally {
80  libxml_use_internal_errors($previousSetting);
81  libxml_disable_entity_loader($previousEntityState);
82  }
83 
84  return $result;
85  }
86 
87 
88 
105  function parseGetElements(array $elementMap = null) {
106 
107  $result = $this->parseInnerTree($elementMap);
108  if (!is_array($result)) {
109  return [];
110  }
111  return $result;
112 
113  }
114 
129  function parseInnerTree(array $elementMap = null) {
130 
131  $text = null;
132  $elements = [];
133 
134  if ($this->nodeType === self::ELEMENT && $this->isEmptyElement) {
135  // Easy!
136  $this->next();
137  return null;
138  }
139 
140  if (!is_null($elementMap)) {
141  $this->pushContext();
142  $this->elementMap = $elementMap;
143  }
144 
145  try {
146 
147  // Really sorry about the silence operator, seems like I have no
148  // choice. See:
149  //
150  // https://bugs.php.net/bug.php?id=64230
151  if (!@$this->read()) {
152  $errors = libxml_get_errors();
153  libxml_clear_errors();
154  if ($errors) {
155  throw new LibXMLException($errors);
156  }
157  throw new ParseException('This should never happen (famous last words)');
158  }
159 
160  while (true) {
161 
162  if (!$this->isValid()) {
163 
164  $errors = libxml_get_errors();
165 
166  if ($errors) {
167  libxml_clear_errors();
168  throw new LibXMLException($errors);
169  }
170  }
171 
172  switch ($this->nodeType) {
173  case self::ELEMENT :
174  $elements[] = $this->parseCurrentElement();
175  break;
176  case self::TEXT :
177  case self::CDATA :
178  $text .= $this->value;
179  $this->read();
180  break;
181  case self::END_ELEMENT :
182  // Ensuring we are moving the cursor after the end element.
183  $this->read();
184  break 2;
185  case self::NONE :
186  throw new ParseException('We hit the end of the document prematurely. This likely means that some parser "eats" too many elements. Do not attempt to continue parsing.');
187  default :
188  // Advance to the next element
189  $this->read();
190  break;
191  }
192 
193  }
194 
195  } finally {
196 
197  if (!is_null($elementMap)) {
198  $this->popContext();
199  }
200 
201  }
202  return ($elements ? $elements : $text);
203 
204  }
205 
211  function readText() {
212 
213  $result = '';
214  $previousDepth = $this->depth;
215 
216  while ($this->read() && $this->depth != $previousDepth) {
217  if (in_array($this->nodeType, [XMLReader::TEXT, XMLReader::CDATA, XMLReader::WHITESPACE])) {
218  $result .= $this->value;
219  }
220  }
221  return $result;
222 
223  }
224 
235  function parseCurrentElement() {
236 
237  $name = $this->getClark();
238 
239  $attributes = [];
240 
241  if ($this->hasAttributes) {
242  $attributes = $this->parseAttributes();
243  }
244 
245  $value = call_user_func(
247  $this
248  );
249 
250  return [
251  'name' => $name,
252  'value' => $value,
253  'attributes' => $attributes,
254  ];
255  }
256 
257 
268  function parseAttributes() {
269 
270  $attributes = [];
271 
272  while ($this->moveToNextAttribute()) {
273  if ($this->namespaceURI) {
274 
275  // Ignoring 'xmlns', it doesn't make any sense.
276  if ($this->namespaceURI === 'http://www.w3.org/2000/xmlns/') {
277  continue;
278  }
279 
280  $name = $this->getClark();
281  $attributes[$name] = $this->value;
282 
283  } else {
284  $attributes[$this->localName] = $this->value;
285  }
286  }
287  $this->moveToElement();
288 
289  return $attributes;
290 
291  }
292 
301 
302 
303  if (!array_key_exists($name, $this->elementMap)) {
304  if (substr($name, 0, 2) == '{}' && array_key_exists(substr($name, 2), $this->elementMap)) {
305  $name = substr($name, 2);
306  } else {
307  return ['Sabre\\Xml\\Element\\Base', 'xmlDeserialize'];
308  }
309  }
310 
311  $deserializer = $this->elementMap[$name];
312  if (is_subclass_of($deserializer, 'Sabre\\Xml\\XmlDeserializable')) {
313  return [$deserializer, 'xmlDeserialize'];
314  }
315 
316  if (is_callable($deserializer)) {
317  return $deserializer;
318  }
319 
320  $type = gettype($deserializer);
321  if ($type === 'string') {
322  $type .= ' (' . $deserializer . ')';
323  } elseif ($type === 'object') {
324  $type .= ' (' . get_class($deserializer) . ')';
325  }
326  throw new \LogicException('Could not use this type as a deserializer: ' . $type . ' for element: ' . $name);
327 
328  }
329 
330 }
parseInnerTree(array $elementMap=null)
Parses all elements below the current element.
Definition: Reader.php:129
getDeserializerForElementName($name)
Returns the function that should be used to parse the element identified by it&#39;s clark-notation name...
Definition: Reader.php:300
parseAttributes()
Grabs all the attributes from the current element, and returns them as a key-value array...
Definition: Reader.php:268
parse()
Reads the entire document.
Definition: Reader.php:57
This is a base exception for any exception related to parsing xml files.
$result
trait ContextStackTrait
Context Stack.
$type
popContext()
Restore the previous "context".
parseGetElements(array $elementMap=null)
parseGetElements parses everything in the current sub-tree, and returns a an array of elements...
Definition: Reader.php:105
parseCurrentElement()
Parses the current XML element.
Definition: Reader.php:235
This exception is thrown when the Readers runs into a parsing error.
The Reader class expands upon PHP&#39;s built-in XMLReader.
Definition: Reader.php:20
pushContext()
Create a new "context".
$text
Definition: errorreport.php:18
if(array_key_exists('yes', $_REQUEST)) $attributes
Definition: getconsent.php:85
readText()
Reads all text below the current element, and returns this as a string.
Definition: Reader.php:211
$errors
Definition: index.php:6
getClark()
Returns the current nodename in clark-notation.
Definition: Reader.php:34