=') && extension_loaded('xsl')) { require_once($include_path.'/xslt-php4-to-php5.inc.php'); } class xml_dom_lehmanns { public $xml; /*!< XML d'origine */ public $charset; /*!< Charset courant (iso-8859-1 ou utf-8) */ /** * \brief Arbre des noeuds du document * * L'arbre est composé de noeuds qui ont la structure suivante : * \anchor noeud * \verbatim $noeud = array( NAME => 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.=""; } } 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 lehmanns extends connector { //Variables internes pour la progression de la récupération des notices public $themes=array( "Humanmedizin", "Psychologie", "Informatik", "Veterinärmedizin", "Naturwissenschaft", "Technik", "Recht", "Wirtschaft" ); public function __construct($connector_path="") { parent::__construct($connector_path); } public function get_id() { return "lehmanns"; } //Est-ce un entrepot ? public function is_repository() { return 2; } public function source_get_property_form($source_id) { global $charset, $max_return, $themes; $params=$this->get_source_params($source_id); if ($params["PARAMETERS"]) { //Affichage du formulaire avec $params["PARAMETERS"] $vars=unserialize($params["PARAMETERS"]); foreach ($vars as $key=>$val) { global ${$key}; ${$key}=$val; } } if ($themes=="") $themes=array(); $form="
"; return $form; } public function make_serialized_source_properties($source_id) { global $themes,$max_return; if ($themes[0]=="") $themes=array(); $t["themes"]=$themes; $t["max_return"]=$max_return; $this->sources[$source_id]["PARAMETERS"]=serialize($t); } //Récupération des proriétés globales par défaut du connecteur (timeout, retry, repository, parameters) public function fetch_default_global_values() { parent::fetch_default_global_values(); $this->repository=1; $this->parameters=array(); } //Fonction de recherche public function search($source_id,$query,$search_id) { global $charset; global $pmb_curl_proxy; global $base_path; $this->error=false; $this->error_message=""; $params=$this->get_source_params($source_id); $this->fetch_global_properties(); if ($params["PARAMETERS"]) { //Affichage du formulaire avec $params["PARAMETERS"] $vars=unserialize($params["PARAMETERS"]); foreach ($vars as $key=>$val) { global ${$key}; ${$key}=$val; } } if (!$max_return) $max_return=100; //Construction de la requête $boolsearch=""; for ($i=0; $iufield) { case "200\$a": $chaine="(TI=".str_replace("*","%",$term->values[0])." or ST=".str_replace("*","%",$term->values[0]).")"; break; case "010\$a": $chaine="IS=".str_replace("*","%",$term->values[0]); break; case "7XX": $chaine="AU=".str_replace("*","%",$term->values[0]); break; case "210\$c": $chaine="PU=".str_replace("*","%",$term->values[0]); break; case "210\$d": $chaine="PY=".str_replace("*","%",$term->values[0]); break; case "300": case "327": case "330": case "3XX": $chaine="ME=".str_replace("*","%",$term->values[0]); break; case "60X": $chaine="FT=".str_replace("*","%",$term->values[0]); break; case "XXX": $chaine="(TI=".str_replace("*","%",$term->values[0])." or ST=".str_replace("*","%",$term->values[0])." or AU=".str_replace("*","%",$term->values[0])." or FT=".str_replace("*","%",$term->values[0])." or ME=".str_replace("*","%",$term->values[0])." or IS=".str_replace("*","%",$term->values[0])." or PU=".str_replace("*","%",$term->values[0]).")"; break; } if (($chaine!="")&&($i!=0)) { switch ($term->inter) { case "and": $boolsearch.=" and "; break; case "or": $boolsearch.=" or "; break; case "ex": $boolsearch.=" and not "; break; } } $boolsearch.=$chaine; } $boolthemes=""; if (count($themes)) { for ($i=0; $ierror=true; $this->error_message="Can't get Lob answer : ".curl_error($ch); break; } else { if (strpos($cexec,"")!==false) { $unixml=$this->apply_xsl_to_xml($cexec,file_get_contents($base_path."/admin/connecteurs/in/lehmanns/xslt/lehmanns2uni.xsl")); $this->rec_records($unixml, $source_id, $search_id); } else $stop=true; } curl_close($ch); if ($stop) break; } } public function rec_records($noticesxml, $source_id, $search_id) { global $charset,$base_path; if (!trim($noticesxml)) return; $rec_uni_dom=new xml_dom_lehmanns($noticesxml,"iso-8859-1"); $notices=$rec_uni_dom->get_nodes("unimarc/notice"); if ($notices) { foreach ($notices as $anotice) { $this->rec_record($rec_uni_dom, $anotice, $source_id, $search_id); } } } public function rec_record($rec_uni_dom,$noticenode, $source_id, $search_id) { global $charset,$base_path; $date_import=date("Y-m-d H:i:s",time()); if (!$rec_uni_dom->error) { //Initialisation $ref=""; $ufield=""; $usubfield=""; $field_order=0; $subfield_order=0; $value=""; $fs=$rec_uni_dom->get_nodes("f", $noticenode); //Recherche du 001 for ($i=0; $iget_datas($fs[$i]); break; } } //Mise à jour if ($ref) { //Si conservation des anciennes notices, on regarde si elle existe if (!$this->del_old) { $ref_exists = $this->has_ref($source_id, $ref, $search_id); } //Si pas de conservation des anciennes notices, on supprime if ($this->del_old) { $this->delete_from_entrepot($source_id, $ref, $search_id); $this->delete_from_external_count($source_id, $ref); } //Si pas de conservation ou reférence inexistante if (($this->del_old)||((!$this->del_old)&&(!$ref_exists))) { //Insertion de l'entête $n_header["rs"]=$rec_uni_dom->get_value("unimarc/notice/rs"); $n_header["ru"]=$rec_uni_dom->get_value("unimarc/notice/ru"); $n_header["el"]=$rec_uni_dom->get_value("unimarc/notice/el"); $n_header["bl"]=$rec_uni_dom->get_value("unimarc/notice/bl"); $n_header["hl"]=$rec_uni_dom->get_value("unimarc/notice/hl"); $n_header["dt"]=$rec_uni_dom->get_value("unimarc/notice/dt"); //Récupération d'un ID $recid = $this->insert_into_external_count($source_id, $ref); $rqt_parallel="insert into entrepot_source_".$source_id." (connector_id,source_id,ref,date_import,ufield,usubfield,field_order,subfield_order,value,i_value,recid,search_id) values"; $first=false; foreach($n_header as $hc=>$code) { /*$requete="insert into entrepot_source_".$source_id." (connector_id,source_id,ref,date_import,ufield,usubfield,field_order,subfield_order,value,i_value,recid,search_id) values( '".addslashes($this->get_id())."',".$source_id.",'".addslashes($ref)."','".addslashes($date_import)."', '".$hc."','',-1,0,'".addslashes($code)."','',$recid,'".addslashes($search_id)."')"; pmb_mysql_query($requete);*/ $rqt_parallel.=($first?",":"")."( '".addslashes($this->get_id())."',".$source_id.",'".addslashes($ref)."','".addslashes($date_import)."', '".$hc."','',-1,0,'".addslashes($code)."','',$recid,'".addslashes($search_id)."')"; $first=true; } for ($i=0; $iget_nodes("s",$fs[$i]); if (is_array($ss)) { for ($j=0; $jget_datas($ss[$j]); $subfield_order=$j; /*$requete="insert into entrepot_source_".$source_id." (connector_id,source_id,ref,date_import,ufield,usubfield,field_order,subfield_order,value,i_value,recid,search_id) values( '".addslashes($this->get_id())."',".$source_id.",'".addslashes($ref)."','".addslashes($date_import)."', '".addslashes($ufield)."','".addslashes($usubfield)."',".$field_order.",".$subfield_order.",'".addslashes($value)."', ' ".addslashes(strip_empty_words($value))." ',$recid,'".addslashes($search_id)."')"; pmb_mysql_query($requete);*/ $rqt_parallel.=",( '".addslashes($this->get_id())."',".$source_id.",'".addslashes($ref)."','".addslashes($date_import)."', '".addslashes($ufield)."','".addslashes($usubfield)."',".$field_order.",".$subfield_order.",'".addslashes($value)."', ' ".addslashes(strip_empty_words($value))." ',$recid,'".addslashes($search_id)."')"; } } else { $value=$rec_uni_dom->get_datas($fs[$i]); /*$requete="insert into entrepot_source_".$source_id." (connector_id,source_id,ref,date_import,ufield,usubfield,field_order,subfield_order,value,i_value,recid,search_id) values( '".addslashes($this->get_id())."',".$source_id.",'".addslashes($ref)."','".addslashes($date_import)."', '".addslashes($ufield)."','".addslashes($usubfield)."',".$field_order.",".$subfield_order.",'".addslashes($value)."', ' ".addslashes(strip_empty_words($value))." ',$recid,'".addslashes($search_id)."')"; pmb_mysql_query($requete);*/ $rqt_parallel.=",( '".addslashes($this->get_id())."',".$source_id.",'".addslashes($ref)."','".addslashes($date_import)."', '".addslashes($ufield)."','".addslashes($usubfield)."',".$field_order.",".$subfield_order.",'".addslashes($value)."', ' ".addslashes(strip_empty_words($value))." ',$recid,'".addslashes($search_id)."')"; } } pmb_mysql_query($rqt_parallel); //print $rqt_parallel."\n"; $this->rec_isbd_record($source_id, $ref, $recid); } } } } } ?>