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>\\1>',$testxml); // =>
if ((stripos($testxml, '@','',$testxml);
$testxml = preg_replace('@@i','',$testxml);
$m = array();
preg_match('@<(\\S+?)[^>]*>(.*)\\1>@smU',$testxml,$m); // find root element
$root_element = $m[1];
} else {
$root_element = null;
}
$m = array();
preg_match_all('@<(\\S+?)([^>]*)>(.*)\\1>@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;
}
}
}