array will include them $_simplexml_supplement_properties = array(); function simplexml_load_file($file): SimpleXMLElement { return simplexml_load_string(file_get_contents($file)); } function simplexml_load_string($testxml): SimpleXMLElement { $out = new SimpleXMLElement(); /** @phpstan-ignore-line */ $testxml = preg_replace('@@','',$testxml); // remove comments $testxml = preg_replace('@<([^>\\s]+)\\s*/>@smU','<\\1>',$testxml); // => if ((stripos($testxml, '@','',$testxml); $testxml = preg_replace('@@i','',$testxml); $m = array(); preg_match('@<(\\S+?)[^>]*>(.*)@smU',$testxml,$m); // find root element $root_element = $m[1]; } else { $root_element = null; } $m = array(); preg_match_all('@<(\\S+?)([^>]*)>(.*)@smU', $testxml, $m, PREG_SET_ORDER); foreach ($m as $n) { $name = $n[1]; $other = $n[2]; $val = $n[3]; // We are using chr(1) to avoid that is parsed as child if it follows CDATA immediately $val = str_replace('', chr(1), $val); $val = trim($val); $new = $out->addChild($name, $val); $m2 = array(); preg_match_all('@(\S+)=\\"([^\\"]+)\\"@smU', $other, $m2, PREG_SET_ORDER); foreach ($m2 as $n2) { $att_name = $n2[1]; $att_val = $n2[2]; $new->addAttribute($att_name, $att_val); } } if (!is_null($root_element)) { $out = $out->$root_element; } return $out; } class SimpleXMLElement implements ArrayAccess, Iterator { /** @phpstan-ignore-line */ function __destruct() { global $_simplexml_supplement_properties; unset($_simplexml_supplement_properties[spl_object_hash($this)]); } public function addAttribute($name, $val) { global $_simplexml_supplement_properties; $_simplexml_supplement_properties[spl_object_hash($this)]['attrs'][$name] = $val; } public function attributes() { global $_simplexml_supplement_properties; return $_simplexml_supplement_properties[spl_object_hash($this)]['attrs']; } public function isSupplement() { return true; } public function __construct($val=null) { global $_simplexml_supplement_properties; $_simplexml_supplement_properties[spl_object_hash($this)] = array( "position" => 0, "attrs" => array() ); if (!is_null($val)) { $this->{_simplexml_supplement_addnumberprefix(0)} = $val; } } public function isArray() { $vars = get_object_vars($this); $max = -1; foreach ($vars as $x => $dummy) { if (!_simplexml_supplement_isnumeric($x)) { $max = -1; break; } else { $num = _simplexml_supplement_getnumber($x); if ($num > $max) $max = $num; } } return $max > 0; } public function addToArray($val) { $vars = get_object_vars($this); $max = -1; foreach ($vars as $x => $dummy) { if (!_simplexml_supplement_isnumeric($x)) { $max = -1; break; } else { $num = _simplexml_supplement_getnumber($x); if ($num > $max) $max = $num; } } $max++; $this->{_simplexml_supplement_addnumberprefix($max)} = $val; } public function __toString() { $data = get_object_vars($this); if (is_array($data)) { if (isset($data[_simplexml_supplement_addnumberprefix(0)])) { return $data[_simplexml_supplement_addnumberprefix(0)]; } else { return ''; } } else { /** @phpstan-ignore-line */ return $data; } } public function offsetExists($offset) { return isset($this->$offset); } public function offsetGet($offset) { return $this->$offset; } public function offsetSet($offset, $value) { $this->$offset = $value; } public function offsetUnset($offset) { unset($this->$offset); } public function __get($name) { // Output nothing return new SimpleXMLElement(); /** @phpstan-ignore-line */ } public function addChild($name, $val=null) { global $_simplexml_supplement_properties; if ($val == null) $val = new SimpleXMLElement(); /** @phpstan-ignore-line */ if ((substr(trim($val),0,1) === '<') || (trim($val) == '')) { $val = simplexml_load_string($val); } if (is_string($val)) $val = str_replace(chr(1), '', $val); $data = get_object_vars($this); if (!isset($data[$name])) { if ($val instanceof SimpleXMLElement) { $this->$name = $val; } else { $this->$name = new SimpleXMLElement($val); } } else { if (!($val instanceof SimpleXMLElement)) { $val = new SimpleXMLElement($val); } if ($data[$name]->isArray()) { $data[$name]->addToArray($val); } else { $tmp = new SimpleXMLElement(); /** @phpstan-ignore-line */ $tmp->addToArray($data[$name]); $tmp->addToArray($val); $this->$name = $tmp; $_simplexml_supplement_properties[spl_object_hash($this)]['attrs'] = array(); } return $val; } return $this->$name; } public function rewind() { global $_simplexml_supplement_properties; $_simplexml_supplement_properties[spl_object_hash($this)]['position'] = 0; } public function current() { global $_simplexml_supplement_properties; $vars = get_object_vars($this); $cnt = 0; foreach ($vars as $x => $dummy) { /** @phpstan-ignore-line */ if (($dummy instanceof SimpleXMLElement) && !_simplexml_supplement_isnumeric($x) && $dummy->isArray()) { $vars2 = get_object_vars($dummy); foreach ($vars2 as $x2 => $dummy2) { if ($cnt == $_simplexml_supplement_properties[spl_object_hash($this)]['position']) { if ($dummy2 instanceof SimpleXMLElement) { return $dummy2; /** @phpstan-ignore-line */ } else { return new SimpleXMLElement($dummy2); /** @phpstan-ignore-line */ } } $cnt++; } } else { if ($cnt == $_simplexml_supplement_properties[spl_object_hash($this)]['position']) { if ($dummy instanceof SimpleXMLElement) { return $dummy; /** @phpstan-ignore-line */ } else { return new SimpleXMLElement($dummy); /** @phpstan-ignore-line */ } } $cnt++; } } } public function key() { global $_simplexml_supplement_properties; $vars = get_object_vars($this); $cnt = 0; foreach ($vars as $x => $dummy) { /** @phpstan-ignore-line */ if (($dummy instanceof SimpleXMLElement) && !_simplexml_supplement_isnumeric($x) && $dummy->isArray()) { $vars2 = get_object_vars($dummy); foreach ($vars2 as $x2 => $dummy2) { if ($cnt == $_simplexml_supplement_properties[spl_object_hash($this)]['position']) return $x/*sic*/; $cnt++; } } else { if ($cnt == $_simplexml_supplement_properties[spl_object_hash($this)]['position']) return $x; $cnt++; } } } public function next() { global $_simplexml_supplement_properties; ++$_simplexml_supplement_properties[spl_object_hash($this)]['position']; } public function valid() { global $_simplexml_supplement_properties; $vars = get_object_vars($this); $cnt = 0; foreach ($vars as $x => $dummy) { if (($dummy instanceof SimpleXMLElement) && !_simplexml_supplement_isnumeric($x) && $dummy->isArray()) { $vars2 = get_object_vars($dummy); foreach ($vars2 as $x2 => $dummy2) { $cnt++; } } else { $cnt++; } } return $_simplexml_supplement_properties[spl_object_hash($this)]['position'] < $cnt; } } }