public static function &loadString($xmlString, $separatorChar = System::crlf) { $rv = null; $lines = explode($separatorChar, $xmlString); if (count($lines) == 0) { throw new IllegalArgumentException('données xml non valides'); } else { $declaration = trim(array_shift($lines)); $matches = array(); preg_match('/<\\?xml(.*?)\\?>$/', $declaration, $matches); // preg_match( '/^<\?xml(.*?)\?'.'>$/', $declaration, $matches ); // supprimé à cause du BOM des fichiers UTF8 if (0 == count($matches)) { throw new IllegalArgumentException('La déclaration xml est manquante ou incorrecte'); } else { $rv = new xmlDocument(); // analyse de la déclaration xml preg_match_all('/([a-z0-9_-]+)="(.+)"/U', $matches[1], $matches); if (count($matches) > 0) { $n_attributes = count($matches[0]); for ($i = 0; $i < $n_attributes; $i++) { switch (strtolower($matches[1][$i])) { case 'encoding': $rv->setEncoding($matches[2][$i]); break; case 'version': $rv->setVersion($matches[2][$i]); break; case 'standalone': $rv->setStandalone($matches[2][$i]); break; } } } // analyse des noeuds $tmp = implode(System::crlf, $lines); preg_match_all('/<([^>\\s]*?)([^>]*?)>([^<]*?)/Uims', $tmp, $matches); if (count($matches) > 0) { $specialNodeFirstChar = array('!', '?'); $n_entity = count($matches[0]); $parentNode =& $rv; $newNode = null; $lastNodenodeName = $lastNodeHasChild = null; for ($i = 0; $i < $n_entity; $i++) { $isCloseTag = '/' == $matches[1][$i][0]; $isSpecialNode = !$isCloseTag && in_array($matches[1][$i][0], $specialNodeFirstChar); $nodeName = $isCloseTag ? substr($matches[1][$i], 1) : $matches[1][$i]; if ('/' == substr($nodeName, -1)) { $nodeName = substr($nodeName, 0, -1); } $hasChild = !$isSpecialNode && !$isCloseTag && '/' != substr(trim($matches[2][$i]), -1); $text = trim($matches[3][$i]); if ($isCloseTag) { $parentNode =& $newNode->parentNode(); if (strlen($text) > 0) { $tmp =& $parentNode->parentNode(); $tmp->appendChild(new xmlTextNode($text)); } $newNode =& $parentNode; } else { if (!is_null($newNode)) { if ($lastNodenodeName == $nodeName) { $parentNode =& $newNode->parentNode(); } else { if ($lastNodeHasChild) { $parentNode =& $newNode; } else { $parentNode =& $newNode->parentNode(); } } } if ($isSpecialNode) { $specialType = substr($nodeName, 0, 1); $nodeName = substr($nodeName, 1); if ('!' == $specialType) { $value = substr(rtrim($matches[0][$i]), 2, -1); $isCData = '[CDATA[' == substr($value, 0, 7); if ($isCData) { $nodeName = '[CDATA['; $newNode =& new xmlCDataSection(substr($value, strlen($nodeName), -2)); } else { $nodeName = '--'; $newNode =& new xmlComment(substr($value, strlen($nodeName), -2)); } } elseif ('?' == $specialType) { $newNode =& new xmlProcessingInstruction(); } else { trigger_error('Type inconnu', E_USER_WARNING); } } else { $newNode =& new xmlElement($nodeName); } $newNode->nodeName($nodeName); $attributes = array(); preg_match_all('/([a-z0-9_:-]+)="(.+)"/U', $matches[2][$i], $attributes); if (count($attributes) > 0 && count($attributes[0]) > 0) { foreach ($attributes[1] as $idx => $key) { $newNode->setAttribute($key, $attributes[2][$idx]); } } if (!is_null($parentNode)) { $parentNode->appendChild($newNode); } $lastNodenodeName = $nodeName; $lastNodeHasChild = $hasChild; if (strlen($text) > 0) { if ($hasChild) { $newNode->appendChild(new xmlTextNode($text)); } else { $parentNode->appendChild(new xmlTextNode($text)); } } } } } } } return $rv; }