1. ¿Están bien anidadas las etiquetas?
Medio · Fundamentos de Lenguajes de Marcas · apuntesdam.com/subject/lenguajes-marcas/topic/fundamentos
Un documento XML bien formado tiene un único elemento raíz y todas sus etiquetas cerradas en orden inverso al de apertura. Lee el documento completo y recorre sus etiquetas (ya están extraídas con una expresión regular; se ignoran <?…?>, comentarios y DOCTYPE). Las de cierre son </nombre>, las vacías terminan en /> y el resto son de apertura (el nombre es lo que va tras < hasta un espacio, / o >). Detén la comprobación en el primer error: «Error en la línea L: </x> no tiene etiqueta de apertura», «Error en la línea L: se esperaba </a> pero aparece </b>», «Error en la línea L: <x> es un segundo elemento raíz» (si empieza un elemento cuando la raíz ya se cerró), y al final «Error: falta cerrar <x>» (la más interna) o «Error: el documento no tiene elemento raíz». Si todo es correcto: «Bien formado: N elementos, profundidad máxima D, raíz <r>» (la raíz tiene profundidad 1). Los nombres distinguen mayúsculas.
import re, sys texto = sys.stdin.read() def linea(pos): return texto.count("\n", 0, pos) + 1 pila = [] # etiquetas abiertaselementos = 0profundidad = 0raiz = None # nombre de la raíz cuando ya se ha cerradofor m in re.finditer(r"<[^>]*>", texto): etiqueta = m.group() if etiqueta.startswith(("<?", "<!")): continue # declaración, comentarios y DOCTYPE no cuentan # TODO: etiquetas de cierre, vacías y de aperturaprint("Bien formado")Ejemplo: Catálogo correcto
Entrada
<?xml version="1.0" encoding="UTF-8"?>
<!-- Catálogo de la biblioteca -->
<biblioteca>
<libro isbn="978-84-1">
<titulo>El Quijote</titulo>
<autor>Cervantes</autor>
<portada archivo="q.jpg"/>
</libro>
<libro isbn="978-84-2">
<titulo>La Regenta</titulo>
</libro>
</biblioteca>Salida esperada
Bien formado: 7 elementos, profundidad máxima 3, raíz <biblioteca>Ejemplo: Cierre cruzado
Entrada
<pedido>
<cliente><nombre>Ana</cliente></nombre>
</pedido>Salida esperada
Error en la línea 2: se esperaba </nombre> pero aparece </cliente>Ejemplo: Dos raíces
Entrada
<a>
</a>
<b/>Salida esperada
Error en la línea 3: <b> es un segundo elemento raízEjemplo: Sin cerrar
Entrada
<html>
<body>
<p>Hola
</body>
</html>Salida esperada
Error en la línea 4: se esperaba </p> pero aparece </body>