X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=www%2Fecrire%2Finc%2Fxml.php;h=d6280ebdf16e56a9c5824ca2659d992b966918eb;hb=4f443dce95ff6f8221c189880a70c74ce1c1f238;hp=3a40fb1eb4d06e908fd1e1e5061a2c884cfdafac;hpb=4a628e9b277d3617535f99d663ca79fa2e891177;p=lhc%2Fweb%2Fwww.git diff --git a/www/ecrire/inc/xml.php b/www/ecrire/inc/xml.php index 3a40fb1e..d6280ebd 100644 --- a/www/ecrire/inc/xml.php +++ b/www/ecrire/inc/xml.php @@ -3,174 +3,267 @@ /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * - * Copyright (c) 2001-2016 * + * Copyright (c) 2001-2017 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ -if (!defined('_ECRIRE_INC_VERSION')) return; +/** + * Outils pour lecture de XML + * + * @package SPIP\Core\XML + **/ -// http://doc.spip.org/@spip_xml_load -function spip_xml_load($fichier, $strict=true, $clean=true, $taille_max = 1048576, $datas='', $profondeur = -1){ +if (!defined('_ECRIRE_INC_VERSION')) { + return; +} + + +/** + * Lit un fichier xml donné et renvoie son arbre. + * + * @example + * ``` + * include_spip('inc/xml'); + * $arbre = spip_xml_load(_DIR_PLUGINS . "$plug/plugin.xml"); + * ``` + * + * @uses spip_xml_parse() + * + * @param string $fichier + * Chemin local ou URL distante du fichier XML + * @param bool $strict + * true pour râler si une balise n'est pas correctement fermée, false sinon. + * @param bool $clean ? + * @param int $taille_max + * Taille maximale si fichier distant + * @param string|array $datas + * Données à envoyer pour récupérer le fichier distant + * @param int $profondeur ? + * @return array|bool + * - array : l'arbre XML, + * - false si l'arbre xml ne peut être créé ou est vide + **/ +function spip_xml_load($fichier, $strict = true, $clean = true, $taille_max = 1048576, $datas = '', $profondeur = -1) { $contenu = ""; - if (preg_match(",^(http|ftp)://,",$fichier)){ + if (tester_url_absolue($fichier)) { include_spip('inc/distant'); - $contenu = recuperer_page($fichier,false,false,$taille_max, $datas); + $contenu = recuperer_page($fichier, false, false, $taille_max, $datas); + } else { + lire_fichier($fichier, $contenu); } - else lire_fichier ($fichier, $contenu); $arbre = array(); - if ($contenu) + if ($contenu) { $arbre = spip_xml_parse($contenu, $strict, $clean, $profondeur); - - return count($arbre)?$arbre:false; + } + + return count($arbre) ? $arbre : false; +} + +if (!defined('_SPIP_XML_TAG_SPLIT')) { + define('_SPIP_XML_TAG_SPLIT', "{<([^:>][^>]*?)>}sS"); } -if (!defined('_SPIP_XML_TAG_SPLIT')) define('_SPIP_XML_TAG_SPLIT', "{<([^:>][^>]*?)>}sS"); -// http://doc.spip.org/@spip_xml_parse -function spip_xml_parse(&$texte, $strict=true, $clean=true, $profondeur = -1){ +/** + * Parse une chaine XML donnée et retourne un tableau. + * + * @see spip_xml_aplatit() pour l'inverse + * + * @param string $texte + * Texte XML + * @param bool $strict + * true pour râler si une balise n'est pas correctement fermée, false sinon. + * @param bool $clean ? + * @param int $profondeur ? + * @return array|bool + * - array : l'arbre XML, + * - false si l'arbre xml ne peut être créé ou est vide + **/ +function spip_xml_parse(&$texte, $strict = true, $clean = true, $profondeur = -1) { $out = array(); - // enlever les commentaires - $charset = 'AUTO'; - if ($clean===true){ - if (preg_match(",<\?xml\s(.*?)encoding=['\"]?(.*?)['\"]?(\s(.*))?\?>,im",$texte,$regs)) - $charset = $regs[2]; - $texte = preg_replace(',,is','',$texte); - $texte = preg_replace(',<\?(.*?)\?>,is','',$texte); + // enlever les commentaires + $charset = 'AUTO'; + if ($clean === true) { + if (preg_match(",<\?xml\s(.*?)encoding=['\"]?(.*?)['\"]?(\s(.*))?\?>,im", $texte, $regs)) { + $charset = $regs[2]; + } + $texte = preg_replace(',,is', '', $texte); + $texte = preg_replace(',<\?(.*?)\?>,is', '', $texte); include_spip('inc/charsets'); $clean = $charset; //$texte = importer_charset($texte,$charset); - } - if (is_string($clean)) $charset = $clean; - $txt = $texte; + } + if (is_string($clean)) { + $charset = $clean; + } + $txt = $texte; // tant qu'il y a des tags - $chars = preg_split(_SPIP_XML_TAG_SPLIT,$txt,2,PREG_SPLIT_DELIM_CAPTURE); - while(count($chars)>=2){ + $chars = preg_split(_SPIP_XML_TAG_SPLIT, $txt, 2, PREG_SPLIT_DELIM_CAPTURE); + while (count($chars) >= 2) { // tag ouvrant //$chars = preg_split("{<([^>]*?)>}s",$txt,2,PREG_SPLIT_DELIM_CAPTURE); - + // $before doit etre vide ou des espaces uniquements! $before = trim($chars[0]); - if (strlen($before)>0) - return importer_charset($texte,$charset);//$texte; // before non vide, donc on est dans du texte - + if (strlen($before) > 0) { + return importer_charset($texte, $charset); + }//$texte; // before non vide, donc on est dans du texte + $tag = rtrim($chars[1]); $txt = $chars[2]; - - if (strncmp($tag,'![CDATA[',8)==0) return importer_charset($texte,$charset);//$texte; - if(substr($tag,-1)=='/'){ // self closing tag - $tag = rtrim(substr($tag,0,strlen($tag)-1)); - $out[$tag][]=""; - } - else{ - $closing_tag = preg_split(",\s|\t|\n|\r,",trim($tag)); - $closing_tag=reset($closing_tag); + + if (strncmp($tag, '![CDATA[', 8) == 0) { + return importer_charset($texte, $charset); + }//$texte; + if (substr($tag, -1) == '/') { // self closing tag + $tag = rtrim(substr($tag, 0, strlen($tag) - 1)); + $out[$tag][] = ""; + } else { + $closing_tag = preg_split(",\s|\t|\n|\r,", trim($tag)); + $closing_tag = reset($closing_tag); // tag fermant $ncclos = strlen(""); - $p = strpos($txt,""); - if ($p!==FALSE AND (strpos($txt,"<")<$p)){ - $nclose =0; $nopen = 0; + $p = strpos($txt, ""); + if ($p !== false and (strpos($txt, "<") < $p)) { + $nclose = 0; + $nopen = 0; $d = 0; while ( - $p!==FALSE - AND ($morceau = substr($txt,$d,$p-$d)) - AND (($nopen+=preg_match_all("{<".preg_quote($closing_tag)."(\s*>|\s[^>]*[^/>]>)}is",$morceau,$matches,PREG_SET_ORDER))>$nclose) - ){ + $p !== false + and ($morceau = substr($txt, $d, $p - $d)) + and (($nopen += preg_match_all("{<" . preg_quote($closing_tag) . "(\s*>|\s[^>]*[^/>]>)}is", $morceau, + $matches, PREG_SET_ORDER)) > $nclose) + ) { $nclose++; - $d=$p+$ncclos; - $p = strpos($txt,"",$d); + $d = $p + $ncclos; + $p = strpos($txt, "", $d); } } - if ($p===FALSE){ - if ($strict){ - $out[$tag][]="erreur : tag fermant $tag manquant::$txt"; + if ($p === false) { + if ($strict) { + $out[$tag][] = "erreur : tag fermant $tag manquant::$txt"; + return $out; - } - else return importer_charset($texte,$charset);//$texte // un tag qui constitue du texte a reporter dans $before + } else { + return importer_charset($texte, $charset); + }//$texte // un tag qui constitue du texte a reporter dans $before + } + $content = substr($txt, 0, $p); + $txt = substr($txt, $p + $ncclos); + if ($profondeur == 0 or strpos($content, "<") === false) // eviter une recursion si pas utile + { + $out[$tag][] = importer_charset($content, $charset); + }//$content; + else { + $out[$tag][] = spip_xml_parse($content, $strict, $clean, $profondeur - 1); } - $content = substr($txt,0,$p); - $txt = substr($txt,$p+$ncclos); - if ($profondeur==0 OR strpos($content,"<")===FALSE) // eviter une recursion si pas utile - $out[$tag][] = importer_charset($content,$charset);//$content; - else - $out[$tag][]=spip_xml_parse($content, $strict, $clean, $profondeur-1); } - $chars = preg_split(_SPIP_XML_TAG_SPLIT,$txt,2,PREG_SPLIT_DELIM_CAPTURE); + $chars = preg_split(_SPIP_XML_TAG_SPLIT, $txt, 2, PREG_SPLIT_DELIM_CAPTURE); } - if (count($out)&&(strlen(trim($txt))==0)) + if (count($out) && (strlen(trim($txt)) == 0)) { return $out; - else - return importer_charset($texte,$charset);//$texte; + } else { + return importer_charset($texte, $charset); + }//$texte; } -// http://doc.spip.org/@spip_xml_aplatit -function spip_xml_aplatit($arbre,$separateur = " "){ +// http://code.spip.net/@spip_xml_aplatit +function spip_xml_aplatit($arbre, $separateur = " ") { $s = ""; - if (is_array($arbre)) - foreach($arbre as $tag=>$feuille){ - if (is_array($feuille)){ - if ($tag!==intval($tag)){ + if (is_array($arbre)) { + foreach ($arbre as $tag => $feuille) { + if (is_array($feuille)) { + if ($tag !== intval($tag)) { $f = spip_xml_aplatit($feuille, $separateur); if (strlen($f)) { - $tagf = explode(" ",$tag); + $tagf = explode(" ", $tag); $tagf = $tagf[0]; - $s.="<$tag>$f"; + $s .= "<$tag>$f"; + } else { + $s .= "<$tag />"; } - else $s.="<$tag />"; + } else { + $s .= spip_xml_aplatit($feuille); } - else - $s.=spip_xml_aplatit($feuille); $s .= $separateur; + } else { + $s .= "$feuille$separateur"; } - else - $s.="$feuille$separateur"; } + } + return strlen($separateur) ? substr($s, 0, -strlen($separateur)) : $s; } -// http://doc.spip.org/@spip_xml_tagname -function spip_xml_tagname($tag){ - if (preg_match(',^([a-z][\w:]*),i',$tag,$reg)) +// http://code.spip.net/@spip_xml_tagname +function spip_xml_tagname($tag) { + if (preg_match(',^([a-z][\w:]*),i', $tag, $reg)) { return $reg[1]; + } + return ""; } -// http://doc.spip.org/@spip_xml_decompose_tag -function spip_xml_decompose_tag($tag){ + +// http://code.spip.net/@spip_xml_decompose_tag +function spip_xml_decompose_tag($tag) { $tagname = spip_xml_tagname($tag); $liste = array(); - $p=strpos($tag,' '); - $tag = substr($tag,$p); - $p=strpos($tag,'='); - while($p!==false){ - $attr = trim(substr($tag,0,$p)); - $tag = ltrim(substr($tag,$p+1)); + $p = strpos($tag, ' '); + $tag = substr($tag, $p); + $p = strpos($tag, '='); + while ($p !== false) { + $attr = trim(substr($tag, 0, $p)); + $tag = ltrim(substr($tag, $p + 1)); $quote = $tag{0}; - $p=strpos($tag,$quote,1); - $cont = substr($tag,1,$p-1); + $p = strpos($tag, $quote, 1); + $cont = substr($tag, 1, $p - 1); $liste[$attr] = $cont; - $tag = substr($tag,$p+1); - $p=strpos($tag,'='); + $tag = substr($tag, $p + 1); + $p = strpos($tag, '='); } - return array($tagname,$liste); + + return array($tagname, $liste); } -// http://doc.spip.org/@spip_xml_match_nodes -function spip_xml_match_nodes($regexp,&$arbre,&$matches,$init=true){ - if ($init) +/** + * Recherche dans un arbre XML généré par `spip_xml_parse()` (ou une branche de cet arbre) + * les clés de l'arbre qui valident la regexp donnée. + * + * Les branches qui valident la regexp sont retournées dans le tableau `$matches`. + * + * @see spip_xml_parse() + * @see spip_xml_decompose_tag() + * + * @param string $regexp + * Expression régulière + * @param array $arbre + * Arbre XML + * @param array $matches + * Branches de l'arbre validant la rexgep + * @param bool $init ? + * @return bool + * false si aucun élément ne valide l'expression régulière, true sinon. + **/ +function spip_xml_match_nodes($regexp, &$arbre, &$matches, $init = true) { + if ($init) { $matches = array(); - if(is_array($arbre) && count($arbre)) - foreach(array_keys($arbre) as $tag){ - if (preg_match($regexp,$tag)) + } + if (is_array($arbre) && count($arbre)) { + foreach (array_keys($arbre) as $tag) { + if (preg_match($regexp, $tag)) { $matches[$tag] = &$arbre[$tag]; - if (is_array($arbre[$tag])) - foreach(array_keys($arbre[$tag]) as $occurences) - spip_xml_match_nodes($regexp,$arbre[$tag][$occurences],$matches,false); + } + if (is_array($arbre[$tag])) { + foreach (array_keys($arbre[$tag]) as $occurences) { + spip_xml_match_nodes($regexp, $arbre[$tag][$occurences], $matches, false); + } + } } + } + return (count($matches)); } - - -?>