diff --git a/ecrire/inc/sax.php b/ecrire/inc/sax.php
index 5e65f34f3a47950f07d72422ee08425e84361f0f..e5f8ee2ba2e6187900ae2d65f05f44e960764a04 100644
--- a/ecrire/inc/sax.php
+++ b/ecrire/inc/sax.php
@@ -188,6 +188,7 @@ function xml_parsestring($phraseur, $data)
  var $ouvrant = array();
  var $reperes = array();
  var $elements = array();
+ var $peres = array();
  var $entites = array();
  var $attributs = array();
  var $ids = array();
diff --git a/ecrire/inc/utils.php b/ecrire/inc/utils.php
index fff139e3e44de7f087bc19d0248177a8b56978b9..f14da669deb93281f6aae1bb2e6c6a812deccc4d 100644
--- a/ecrire/inc/utils.php
+++ b/ecrire/inc/utils.php
@@ -989,8 +989,9 @@ function spip_initialisation($pi=NULL, $pa=NULL, $ti=NULL, $ta=NULL) {
 	define('_SPIP_DUMP', 'dump@stamp@.xml');
 
 	define('_DOCTYPE_ECRIRE', 
-	       // "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n");
-	       "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>");
+		// "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n");
+		"<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>");
+		// "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd'>\n");
 
 	define('_DOCTYPE_AIDE', 
 	       "<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01 Frameset//EN' 'http://www.w3.org/TR/1999/REC-html401-19991224/frameset.dtd'>");
diff --git a/ecrire/inc/validateur.php b/ecrire/inc/validateur.php
index aee7e1b9640a81c3c37c4b3026c99dcb46013730..e8f7717fd2069eedcafbd07b1688f79b14dbb2ef 100644
--- a/ecrire/inc/validateur.php
+++ b/ecrire/inc/validateur.php
@@ -50,8 +50,9 @@ function inc_validateur_dist($data)
 	} 
 	$phraseur_xml->entites = $res;
 
-	// reperer pour chaque noeud ses fils potentiels, sans repetitions,
-	// pour faire une analyse syntaxique sommaire
+	// reperer pour chaque noeud ses fils potentiels.
+	// mais tant pis pour leur eventuel ordre de succession (, * +):
+	// les cas sont rares et si aberrants que interet/temps-de-calcul -> 0
 	$res = array();
 	if (preg_match_all('/<!ELEMENT\s+(\w+)([^>]*)>/', $dtd, $r, PREG_SET_ORDER)) {
 	  foreach($r as $m) {
@@ -59,8 +60,13 @@ function inc_validateur_dist($data)
 	    $val = expanserEntite($val, $phraseur_xml->entites);
 	    $val = array_values(preg_split('/\W+/', $val,-1,PREG_SPLIT_NO_EMPTY));
 	    $res[$nom]= $val;
+	    foreach ($val as $k) {
+		if (!isset($phraseur_xml->peres[$k])
+		OR !in_array($nom, $phraseur_xml->peres[$k]))
+		  $phraseur_xml->peres[$k][]= $nom;
+	    }
 	  }
-	}
+	} 
 	$phraseur_xml->elements = $res;
 
 	$res = array();
@@ -113,13 +119,18 @@ function validerElement($parser, $name, $attrs)
 	  if (isset($ouvrant[$depth])) {
 	    if (preg_match('/^\s*(\w+)/', $ouvrant[$depth], $r)) {
 	      $pere = $r[1];
-	      if (!@in_array($name, $phraseur_xml->elements[$pere]))
-		$phraseur_xml->err[]= " <b>$name</b>" 
-		. _L(" n'est pas un fils de ")
-		. '<b>'
-		.  $pere
-		. '</b>'
-		.  coordonnees_erreur($parser);
+	      if (isset($phraseur_xml->elements[$pere]))
+		if (!@in_array($name, $phraseur_xml->elements[$pere])) {
+		  $bons_peres = @join ('</b>, <b>', $phraseur_xml->peres[$name]);
+		  $phraseur_xml->err[]= " <b>$name</b>" 
+		    . _L(" n'est pas un fils de ")
+		    . '<b>'
+		    .  $pere
+		    . '</b>'
+		    . (!$bons_peres ? '' 
+		       : (_L( '<p style="font-size: 80%"> mais de <b>') . $bons_peres . '</b></p>'))
+		    .  coordonnees_erreur($parser);
+		}
 	    }
 	  }
 	  foreach ($phraseur_xml->attributs[$name] as $n => $v)
diff --git a/ecrire/public/debug.php b/ecrire/public/debug.php
index 1148e4c3f20e6332197abd9cb4a720a291d6eea2..13834a53c610ca58f5143beab65cd60fafc1e067 100644
--- a/ecrire/public/debug.php
+++ b/ecrire/public/debug.php
@@ -538,7 +538,7 @@ function emboite_texte($texte, $fonc='',$self='')
 				$GLOBALS['xhtml_error'],
 				$regs,
 			       PREG_SET_ORDER);
-		$err = '<tr><th>#</th><th>Occ.</th><th>Msg</th><th>L</th><th>Col</th></tr>';
+		$err = '<tr><th>#</th><th>Occ.</th><th>Li.</th><th>Col.</th><th>Err.</th></tr>';
 		$fautifs = array();
 		$i = 0;
 		$encore = array();
@@ -560,14 +560,14 @@ function emboite_texte($texte, $fonc='',$self='')
 			  . "'><td style='text-align: right'>"
 			  . $i
 			  . "</td><td  style='text-align: right'>"
-			  . "$ref/$encore[$msg]</td><td>$msg</td>"
+			  . "$ref/$encore[$msg]</td>"
 			  . "<td  style='text-align: right'><a href='#L"
 			  . $ligne
 			  . "' id='T$i'>"
 			  . $ligne
 			  . "</a></td><td  style='text-align: right'>"
 			  . $fin
-			  . "</td></tr>\n";
+			  . "</td><td>$msg</td></tr>\n";
 			$fautifs[]= array($ligne, $col, $i);
 		}
 		return array(ancre_texte($texte, $fautifs),