diff --git a/.gitattributes b/.gitattributes index 8dd540441f5e2c4c8d5140075e5dd4d67a5082ab..aade0b366ecc9490fc7029cbb3b083f417fbb253 100644 --- a/.gitattributes +++ b/.gitattributes @@ -507,6 +507,7 @@ ecrire/inc/syndic.php -text ecrire/inc/tourner.php -text ecrire/inc/traduire.php -text ecrire/inc/utils.php -text +ecrire/inc/validateur.php -text ecrire/inc/vieilles_defs.php -text ecrire/inc/virtualiser.php -text ecrire/inc/xml.php -text diff --git a/ecrire/inc/sax.php b/ecrire/inc/sax.php index 8ca87552f2b6d39c4cb2ad28fcfd39fc85533986..30ada8f661b0fb062b6764bf178f71c80ff7244c 100644 --- a/ecrire/inc/sax.php +++ b/ecrire/inc/sax.php @@ -10,7 +10,6 @@ * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ - if (!defined("_ECRIRE_INC_VERSION")) return; include_spip('inc/filtres'); @@ -22,6 +21,10 @@ class PhraseurXML { function debutElement($parser, $name, $attrs) { global $phraseur_xml; + + if ($phraseur_xml->elements) + validerElement($parser, $name); + $depth = &$phraseur_xml->depth; $contenu = &$phraseur_xml->contenu; $ouvrant = &$phraseur_xml->ouvrant; @@ -42,6 +45,8 @@ function debutElement($parser, $name, $attrs) $att = ''; $sep = ' '; foreach ($attrs as $k => $v) { + if ($phraseur_xml->attributs) + validerAttribut($parser, $k, $v, $name); $delim = strpos($v, "'") === false ? "'" : '"'; $val = entites_html($v); $att .= $sep . $k . "=" . $delim @@ -159,7 +164,9 @@ function xml_parsestring($xml_parser, $data) _L(" ligne ") . $phraseur_xml->reperes[$phraseur_xml->depth])); - } else $r = $phraseur_xml->res; + } else if ($phraseur_xml->err) + $r = join(', ', $phraseur_xml->err); + else $r = $phraseur_xml->res; return $r; } @@ -169,8 +176,14 @@ function xml_parsestring($xml_parser, $data) var $contenu = array(); var $ouvrant = array(); var $reperes = array(); + var $elements = array(); + var $entites = array(); + var $attributs = array(); + var $err = array(); } + + // http://doc.spip.org/@inc_sax_dist function inc_sax_dist($page, $apply=false) { global $phraseur_xml, $xml_parser; @@ -191,7 +204,8 @@ function inc_sax_dist($page, $apply=false) { $page = ob_get_contents(); ob_end_clean(); } - + if ($validateur = charger_fonction('validateur', 'inc', true)) + $validateur($page); $res = $phraseur_xml->xml_parsestring($xml_parser, $page); xml_parser_free($xml_parser); if ($res[0] != '<') diff --git a/ecrire/inc/validateur.php b/ecrire/inc/validateur.php new file mode 100644 index 0000000000000000000000000000000000000000..8e2c94ea6881f43dbf1041e5de796c2f3465de9e --- /dev/null +++ b/ecrire/inc/validateur.php @@ -0,0 +1,99 @@ +<?php + +/***************************************************************************\ + * SPIP, Systeme de publication pour l'internet * + * * + * Copyright (c) 2001-2006 * + * 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; + +define('_REGEXP_DOCTYPE', + '/^\s*<!DOCTYPE\s+(\w+)\s+(\w+)\s+(.)([^\3>]*)\3\s+(.)([^\5>]*)\5[^>]*>/'); + +function inc_validateur_dist($data) +{ + global $phraseur_xml; + + if (!preg_match(_REGEXP_DOCTYPE, $data, $r)) + return array(); + + list(,$ns, $type, $s, $nom, $s2, $grammaire) = $r; + + include_spip('inc/distant'); + $dtd = recuperer_page($grammaire); + preg_match_all('/<!ELEMENT\s+(\w+)[^>]*>/', $dtd, $r); + $phraseur_xml->elements = $r[1]; + + $res = array(); + // on ignore les entites publiques. A ameliorer a terme + if (preg_match_all('/<!ENTITY\s+%\s+([.\w]+)\s+"([^"]*)"\s*>/', $dtd, $r, PREG_SET_ORDER)) { + foreach($r as $m) { + list(,$nom, $val) = $m; + if (preg_match_all('/%([.\w]+);/', $val, $r2, PREG_SET_ORDER)) { + foreach($r2 as $m2) + $val = str_replace($m2[0], $res[$m2[1]], $val); + } + $res[$nom] = $val; + } + } + $phraseur_xml->entites = $res; + + $res = array(); + if (preg_match_all('/<!ATTLIST\s+(\S+)\s+([^>]*)>/', $dtd, $r, PREG_SET_ORDER)) { + foreach($r as $m) { + list(,$nom, $val) = $m; + if (preg_match_all('/%([.\w]+);/', $val, $r2, PREG_SET_ORDER)) { + foreach($r2 as $m2) + // parfois faux suite au non chargement des entites publiques + if ($x = $phraseur_xml->entites[$m2[1]]) + $val = str_replace($m2[0], $x, $val); + } + $att = array(); + if (preg_match_all("/\s*(\S+)\s+(([(][^)]*[)])|(\S+))\s+(\S+)(\s*'[^']*')?/", $val, $r2, PREG_SET_ORDER)) { + foreach($r2 as $m2) + $att[$m2[1]] = $m2[5]; + } + $res[$nom] = $att; + } + } + $phraseur_xml->attributs = $res; +} + +function validerElement($parser, $name) +{ + global $phraseur_xml; + + if ($phraseur_xml->elements + AND !in_array($name, $phraseur_xml->elements)) + + $phraseur_xml->err[]= $name + . ' : ' + . _L('balise inconnue ') + . _L('ligne ') + . xml_get_current_line_number($parser); +} + + +function validerAttribut($parser, $name, $val, $bal) +{ + global $phraseur_xml; + + if ($a = $phraseur_xml->attributs[$bal] + AND !isset($a[$name])) + + $phraseur_xml->err[]= $name + . ' : ' + . _L('attribut inconnu de ') + . $bal + . _L(' ligne ') + . xml_get_current_line_number($parser); +} + + +?>