Blame | Last modification | View Log | RSS feed
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Copyright (c) 2001-2005 *
* 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. *
\***************************************************************************/
//
// Ce fichier ne sera execute qu'une fois
if (defined("INC_PHRASEUR_XML")) return;
define("INC__PHRASEUR_XML", "1");
class PhraseurXML {
function debutElement($parser, $name, $attrs)
{
global $phraseur_xml;
$depth = &$phraseur_xml->depth;
$contenu = &$phraseur_xml->contenu;
$ouvrant = &$phraseur_xml->ouvrant;
$reperes = &$phraseur_xml->reperes;
$res = &$phraseur_xml->res;
$t = $ouvrant[$depth];
// espace initial signifie: deja integree au resultat
if ($t && $t[0] != ' ')
{
$res .= '<' . $t . '>';
$ouvrant[$depth] = ' ' . $t;
}
$t = $contenu[$depth];
// n'indenter que s'il y a un separateur avant
$res .= ereg_replace("[\n\t ]+$", "\n$depth", $t);
$contenu[$depth] = "";
$att = '';
$sep = ' ';
foreach ($attrs as $k => $v) {
$delim = strpos($v, "'") === false ? "'" : '"';
$att .= $sep . $k . "=" . $delim
. str_replace('"', '"', $phraseur_xml->translate_entities($v))
. $delim;
$sep = "\n $depth";
}
$depth .= ' ';
$contenu[$depth] = "";
$ouvrant[$depth] = $name . $att;
$reperes[$depth] = xml_get_current_line_number($parser);
}
function finElement($parser, $name)
{
global $phraseur_xml;
$depth = &$phraseur_xml->depth;
$contenu = &$phraseur_xml->contenu;
$ouvrant = &$phraseur_xml->ouvrant;
$res = &$phraseur_xml->res;
$ouv = $ouvrant[$depth];
if ($ouv[0] != ' ')
$ouvrant[$depth] = ' ' . $ouv;
else $ouv= "";
$t = $contenu[$depth];
$depth = substr($depth, 2);
$t = ereg_replace("[\n\t ]+$", "\n" . $depth, $t);
// fusion <balise></balise> en <balise /> sauf pour qq unes qui hallucinent
if ($t || ($name == 'a') || ($name == 'textarea'))
$res .= ($ouv ? ('<' . $ouv . '>') : '') . $t . "</" . $name . ">";
else
$res .= ($ouv ? ('<' . $ouv . ' />') : ("</" . $name . ">"));
}
function textElement($parser, $data)
{
global $phraseur_xml;
$depth = &$phraseur_xml->depth;
$contenu = &$phraseur_xml->contenu;
$contenu[$depth] .= $phraseur_xml->translate_entities($data);
}
function PiElement($parser, $target, $data)
{
global $phraseur_xml, $xml_parser;
$depth = &$phraseur_xml->depth;
$contenu = &$phraseur_xml->contenu;
if (strtolower($target) != "php")
$contenu[$depth] .= $data;
else {
ob_start();
eval($data);
$data = ob_get_contents();
ob_end_clean();
$contenu[$depth] .= $data;
}
}
function defautElement($parser, $data)
{
global $phraseur_xml;
$depth = &$phraseur_xml->depth;
$contenu = &$phraseur_xml->contenu;
$contenu[$depth] .= $data;
}
function translate_entities($data)
{
return
str_replace('<', '<',
str_replace('>', '>',
ereg_replace('[&]([A-Za-z0-9]*[^A-Za-z0-9;])',
"&\\1",
$data)));
}
function xml_parsefile($xml_parser, $file)
{
if (!($fp = fopen($file, "r"))) {
die("Impossible d'ouvrir le fichier XML");
}
while ($data = fread($fp, 4096)) {
if (!xml_parse($xml_parser, str_replace('’',"'",$data), feof($fp))) {
return (sprintf("erreur XML : %s ligne %d",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)));
}
}
return "";
}
function xml_parsestring($xml_parser, $data)
{
global $phraseur_xml;
$r = "";
if (!xml_parse($xml_parser, $data, true)) {
// ne pas commencer le message par un "<" (cf spip_sax)
$r = xml_error_string(xml_get_error_code($xml_parser)) .
_L(" ligne ") .
xml_get_current_line_number($xml_parser) .
_L(" colonne ") .
xml_get_current_column_number($xml_parser) .
'<br />' .
_L("dernière balise non refermée : ") .
"<tt>" .
$phraseur_xml->ouvrant[$phraseur_xml->depth] .
"</tt>" .
_L(" ligne ") .
$phraseur_xml->reperes[$phraseur_xml->depth];
} else $r = $phraseur_xml->res;
xml_parser_free($xml_parser);
return $r;
}
var $depth = "";
var $res = "";
var $contenu = array();
var $ouvrant = array();
var $reperes = array();
}
// xml_set_objet a utiliser a terme
global $phraseur_xml, $xml_parser;
$phraseur_xml = new PhraseurXML();
$xml_parser = xml_parser_create(lire_meta('charset'));
xml_set_element_handler($xml_parser,
array($phraseur_xml, "debutElement"),
array($phraseur_xml, "finElement"));
xml_set_character_data_handler($xml_parser, array($phraseur_xml, "textElement"));
xml_set_processing_instruction_handler($xml_parser, array($phraseur_xml, 'PiElement'));
xml_set_default_handler($xml_parser, array($phraseur_xml, "defautElement"));
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, false);
function spip_sax($page)
{
global $phraseur_xml, $xml_parser, $xhtml_error;
$res = $phraseur_xml->xml_parsestring($xml_parser, $page);
if ($res[0] != '<')
$xhtml_error = $res;
else
$page = $res;
return $page;
}
// exemple d'appel en ligne de commande:
#$error = $phraseur_xml->xml_parsefile($xml_parser, $_SERVER['argv'][1]);
?>