Nom de l'élément pour un noeud de type élément (TYPE = 1)
ATTRIBS => Tableau des attributs (nom => valeur)
TYPE => 1 = Noeud élément, 2 = Noeud texte
CHILDS => Tableau des noeuds enfants
)
\endverbatim
*/
public $tree;
public $error=false; /*!< Signalement d'erreur : true : erreur lors du parse, false : pas d'erreur */
public $error_message=""; /*!< Message d'erreur correspondant à l'erreur de parse */
public $depth=0; /*!< \protected */
public $last_elt=array(); /*!< \protected */
public $n_elt=array(); /*!< \protected */
public $cur_elt=array(); /*!< \protected */
public $last_char=false; /*!< \protected */
/**
* \protected
*/
public function close_node() {
$this->last_elt[$this->depth-1]["CHILDS"][]=$this->cur_elt;
$this->last_char=false;
$this->cur_elt=$this->last_elt[$this->depth-1];
$this->depth--;
}
/**
* \protected
*/
public function startElement($parser,$name,$attribs) {
if ($this->last_char) $this->close_node();
$this->last_elt[$this->depth]=$this->cur_elt;
$this->cur_elt=array();
$this->cur_elt["NAME"]=$name;
$this->cur_elt["ATTRIBS"]=$attribs;
$this->cur_elt["TYPE"]=1;
$this->last_char=false;
$this->depth++;
}
/**
* \protected
*/
public function endElement($parser,$name) {
if ($this->last_char) $this->close_node();
$this->close_node();
}
/**
* \protected
*/
public function charElement($parser,$char) {
if ($this->last_char) $this->close_node();
$this->last_char=true;
$this->last_elt[$this->depth]=$this->cur_elt;
$this->cur_elt=array();
$this->cur_elt["DATA"].=$char;
$this->cur_elt["TYPE"]=2;
$this->depth++;
}
/**
* \brief Instanciation du parser
*
* Le document xml est parsé selon le charset donné et une représentation sous forme d'arbre est générée
* @param string $xml XML a manipuler
* @param string $charset Charset du document XML
*/
public function __construct($xml,$charset="iso-8859-1") {
$this->charset=$charset;
$this->cur_elt=array("NAME"=>"document","TYPE"=>"0");
//Initialisation du parser
$xml_parser=xml_parser_create($this->charset);
xml_set_object($xml_parser,$this);
xml_parser_set_option( $xml_parser, XML_OPTION_CASE_FOLDING, 0 );
xml_parser_set_option( $xml_parser, XML_OPTION_SKIP_WHITE, 1 );
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser,"charElement");
if (!xml_parse($xml_parser, $xml)) {
$this->error_message=sprintf("XML error: %s at line %d",xml_error_string(xml_get_error_code($xml_parser)),xml_get_current_line_number($xml_parser));
$this->error=true;
}
$this->tree=$this->last_elt[0];
xml_parser_free($xml_parser);
unset($xml_parser);
}
/**
* \anchor path_node
* \brief Récupération d'un noeud par son chemin
*
* Recherche un noeud selon le chemin donné en paramètre. Un noeud de départ peut être précisé
* @param string $path Chemin du noeud recherché
* @param noeud [$node] Noeud de départ de la recherche (le noeud doit être de type 1)
* @return noeud Noeud correspondant au chemin ou \b false si non trouvé
* \note Les chemins ont la syntaxe suivante :
* \verbatim
Texte
Sous texte
Texte 2
a/b/c Le premier noeud élément c (Texte)
a/b/c[2]/d Le premier noeud élément d du deuxième noeud c (Sous texte)
a/b/c[3] Le troisième noeud élément c (Texte 2)
a/b/id@c Le premier noeud élément c (Texte). L'attribut est ignoré
a/b/id@c[3] Le troisème noeud élément c (Texte 2). L'attribut est ignoré
Les attributs ne peuvent être cités que sur le noeud final.
\endverbatim
*/
public function get_node($path, $node = array()) {
if (empty($node)) $node =& $this->tree;
$paths=explode("/",$path);
for ($i=0; $i
Texte
Sous texte
Texte 2
a/b/c Tous les éléments c fils de a/b
a/b/c[2]/d Tous les éléments d fils de a/b et du deuxième élément c
a/b/id@c Tous les noeuds éléments c fils de a/b. L'attribut est ignoré
\endverbatim
*/
public function get_nodes($path,$node="") {
$n=0;
$nodes=[];
while ($nod=$this->get_node($path."[$n]",$node)) {
$nodes[]=$nod;
$n++;
}
return $nodes;
}
/**
* \brief Récupération des données sérialisées d'un noeud élément
*
* Récupère sous forme texte les données d'un noeud élément :\n
* -Si c'est un élément qui n'a qu'un noeud texte comme fils, renvoie le texte\n
* -Si c'est un élément qui a d'autres éléments comme fils, la version sérialisée des enfants est renvoyée
* @param noeud $node Noeud duquel récupérer les données
* @param bool $force_entities true : les données sont renvoyées avec les entités xml, false : les données sont renvoyées sans entités
* @return string données sérialisées du noeud élément
*/
public function get_datas($node,$force_entities=false) {
$char="";
if ($node["TYPE"]!=1) return false;
//Recherche des fils et vérification qu'il n'y a que du texte !
$flag_text=true;
for ($i=0; $icharset);
else $char.=$node["CHILDS"][$i]["DATA"];
else {
$char.="<".$node["CHILDS"][$i]["NAME"];
if (count($node["CHILDS"][$i]["ATTRIBS"])) {
foreach ($node["CHILDS"][$i]["ATTRIBS"] as $key=>$val) {
$char.=" ".$key."=\"".htmlspecialchars($val,ENT_NOQUOTES,$this->charset)."\"";
}
}
$char.=">";
$char.=$this->get_datas($node["CHILDS"][$i],$force_entities);
$char.="".$node["CHILDS"][$i]["NAME"].">";
}
}
return $char;
}
/**
* \brief Récupération des attributs d'un noeud
*
* Renvoie le tableau des attributs d'un noeud élément (Type 1)
* @param noeud $node Noeud élément duquel on veut les attributs
* @return mixed Tableau des attributs Nom => Valeur ou false si ce n'est pas un noeud de type 1
*/
public function get_attributes($node) {
if ($node["TYPE"]!=1) return false;
return $node["ATTRIBUTES"];
}
/**
* \brief Récupère les données ou l'attribut d'un noeud par son chemin
*
* Récupère les données sérialisées d'un noeud ou la valeur d'un attribut selon le chemin
* @param string $path chemin du noeud recherché
* @param noeud $node Noeud de départ de la recherche
* @return string Donnée sérialsiée ou valeur de l'attribut, \b false si le chemin n'existe pas
* \note Exemples de valeurs renvoyées selon le chemin :
* \verbatim
Texte
Sous texte
Texte 2
a/b/c Renvoie : "Texte"
a/b/c[2]/d Renvoie : "Sous texte"
a/b/c[2] Renvoie : "Sous texte"
a/b/c[3] Renvoie : "Texte 2"
a/b/id@c Renvoie : "0"
a/b/id@c[3] Renvoie : "2"
\endverbatim
*/
public function get_value($path,$node="") {
$elt=$this->get_node($path,$node);
if ($elt) {
$paths=explode("/",$path);
$pelt=explode("@",$paths[count($paths)-1]);
if (count($pelt)>1) {
$a=$pelt[0];
//Recherche de l'attribut
if (preg_match("/\[([0-9]*)\]$/",$a,$matches)) {
$attr=substr($a,0,strlen($a)-strlen($matches[0]));
$n=$matches[1];
} else {
$attr=$a;
$n=0;
}
$nc=0;
$found=false;
foreach($elt["ATTRIBS"] as $key=>$val) {
if ($key==$attr) {
//C'est celui là !!
if ($nc==$n) {
$value=$val;
$found=true;
break;
} else $nc++;
}
}
if (!$found) $value="";
} else {
$value=$this->get_datas($elt);
}
}
return $value;
}
/**
* \brief Récupère les données ou l'attribut d'un ensemble de noeuds par leur chemin
*
* Récupère les données sérialisées ou la valeur d'un attribut d'un ensemble de noeuds selon le chemin
* @param string $path chemin des noeuds recherchés
* @param noeud $node Noeud de départ de la recherche
* @return array Tableau des données sérialisées ou des valeur de l'attribut, \b false si le chemin n'existe pas
* \note Exemples de valeurs renvoyées selon le chemin :
* \verbatim
Texte
Sous texte
Texte 2
a/b/c Renvoie : [0]=>"Texte",[1]=>"Sous texte",[2]=>"Texte 2"
a/b/c[2]/d Renvoie : [0]=>"Sous texte"
a/b/id@c Renvoie : [0]=>"0",[1]=>"1",[2]=>"2"
\endverbatim
*/
public function get_values($path,$node="") {
$n=0;
while ($elt=$this->get_node($path."[$n]",$node)) {
$elts[$n]=$elt;
$n++;
}
if (count($elts)) {
for ($i=0; $i1) {
$a=$pelt[0];
//Recherche de l'attribut
if (preg_match("/\[([0-9]*)\]$/",$a,$matches)) {
$attr=substr($a,0,strlen($a)-strlen($matches[0]));
$n=$matches[1];
} else {
$attr=$a;
$n=0;
}
$nc=0;
$found=false;
foreach($elt["ATTRIBS"] as $key=>$val) {
if ($key==$attr) {
//C'est celui là !!
if ($nc==$n) {
$values[]=$val;
$found=true;
break;
} else $nc++;
}
}
if (!$found) $values[]="";
} else {
$values[]=$this->get_datas($elt);
}
}
}
return $values;
}
}
class aligastore_get_data {
public $error=false;
public $error_message="";
public $response_date;
public $charset="iso-8859-1";
public $time_out;
public $xml_parser;
public $retry_after;
public $data = '';
public function __construct($url="", $charset="iso-8859-1", $time_out="") {
$this->charset=$charset;
$this->time_out=$time_out;
if ($url) $this->get_data($url);
}
public function parse_xml($ch,$data) {
if (!$this->retry_after) {
//Parse de la ressource
if (!xml_parse($this->xml_parser, $data)) {
$this->error_message=sprintf("XML error: %s at line %d",xml_error_string(xml_get_error_code($this->xml_parser)),xml_get_current_line_number($this->xml_parser));
$this->error=true;
return strlen($data);
}
}
return strlen($data);
}
public function verif_header($ch,$headers) {
$h=explode("\n",$headers);
for ($i=0; $iretry_after=$v[1]*1; }
}
return strlen($headers);
}
public function get_data($url) {
//Remise à zéro des erreurs
$this->error=false;
$this->error_message="";
//Initialisation de la ressource
$ch = curl_init();
// configuration des options CURL
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_WRITEFUNCTION,array(&$this,"parse_xml"));
curl_setopt($ch, CURLOPT_HEADERFUNCTION,array(&$this,"verif_header"));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
if ($this->time_out) curl_setopt($ch, CURLOPT_TIMEOUT,$this->time_out);
//Réinitialisation du "retry_after"
$this->retry_after="";
//Explosion des arguments de la requète pour ceux qui ne respectent pas la norme !!
$query=substr($url,strpos($url,"?")+1);
$query=explode("&",$query);
for ($i=0; $ixml_parser=xml_parser_create("utf-8");
xml_parser_set_option( $this->xml_parser, XML_OPTION_CASE_FOLDING, 0 );
xml_parser_set_option( $this->xml_parser, XML_OPTION_SKIP_WHITE, 1 );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
configurer_proxy_curl($ch,$url);
$n_try=0;
$data = $cexec=curl_exec($ch);
while (($cexec)&&($this->retry_after)&&($n_try<3)) {
$n_try++;
sleep((int)$this->retry_after*1);
$this->retry_after="";
$data = $cexec=curl_exec($ch);
}
if (!$cexec) {
$this->error=true;
$this->error_message=curl_error($ch);
}
xml_parser_free($this->xml_parser);
$this->xml_parser="";
curl_close($ch);
if ($this->error) { $this->error_message.=" - ".$url; unset($s); return; }
$this->data = $data;
}
}
class aligastore_request {
public $base_url;
public $operation;
public $parameters;
public $error = false;
public $error_message = '';
public $data = '';
public function __construct($base_url, $parameters=array()) {
$this->base_url = $base_url;
$this->parameters = $parameters;
}
public function aligastore_response($charset='ISO-8859-1') {
$parameters = [];
foreach ($this->parameters as $name => $value)
$parameters[] .= $name.'='.urlencode($value);
$url = $this->base_url . '?'.implode('&', $parameters);
$get_data = new aligastore_get_data($url, $charset);
$this->data = $get_data->data;
return $get_data->data;
}
}
?>