Skip to content
Extraits de code Groupes Projets
Valider 4788bd90 rédigé par esj's avatar esj
Parcourir les fichiers

Extension du validateur XML à un validateur lexical selon la DTD.

Le petit validateur construit autour de SAX va à présent chercher la DTD indiqué par la page des espaces public ou privé, à analyser, et vérifie que toutes les balises de la page sont présentes dans la DTD, et que tous les attributs figurant dans une balise sont autorisés par la DTD.

Attention, cette analyse est seulement lexicale, pas syntaxique: on ne vérifie pas qu'un attribut obligatoire est présent, ni que la succession des balises est conforme (ça laisse passer des Form imbriqués par exemple). De plus, les entités déclarées externes ne sont pas traitées. Ca permet néanmoins de répérer les fautes les plus grossières sans passer par les validateurs externes complets, qui n'ont pas accès par URL aux pages calculées par les scripts de l'espace privé faute de Login. Cette vérification s'obtient en mettant:
$GLOBALS['xml_indent'] = 'sax';
dans mes_options.php.

A signaler à propos de ce validateur/indenteur, un bug non résolu mais à présent identifié. Le modèle SAX appelle une fonction définissable par le programmeur (le ''handler'', en français le ''preneur'') à chaque rencontre d'un lexème, en particulier les entités HTML comme "& eacute ;" etc. Ces entités se rencontrent dans les éléments Text et dans les attributs, ce qui provoque l'appel du preneur dans 2 contextes différents sans qu'il puisse les distinguer. Il s'ensuit que l'indenteur mettra à tort dans la dernière zone Texte les entités HTML (typiquement les lettres accentuées) présentes dans les attributs de la balise suivant cette zone. Si quelqu'un a une solution pour contourner ce bug de conception de SAX, je suis ... preneur.
parent bce558ab
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
......@@ -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
......
......@@ -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] != '<')
......
<?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
. '&nbsp;:&nbsp;'
. _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
. '&nbsp;:&nbsp;'
. _L('attribut inconnu de ')
. $bal
. _L(' ligne ')
. xml_get_current_line_number($parser);
}
?>
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter