Un documento XML puede fallar en dos niveles distintos: no estar bien formado (sintaxis rota: una etiqueta sin cerrar, un `&` suelto, dos raíces) o no ser válido según un esquema (estructura correcta pero campos que no cumplen las reglas). Este validador comprueba lo primero con el `DOMParser` del navegador y te señala línea y columna del error, que es lo que necesitas cuando un sistema receptor te devuelve un rechazo genérico.
Well-formed frente a válido
Well-formed significa cumplir las reglas de sintaxis de XML 1.0: un único elemento raíz, todas las etiquetas cerradas y correctamente anidadas, nombres de atributo únicos por elemento, valores siempre entrecomillados y los cinco caracteres especiales escapados. Válido añade la conformidad con un DTD, un XSD o un esquema Relax NG: que exista el elemento obligatorio, que la fecha tenga formato de fecha, que el importe sea decimal. Un documento puede estar perfectamente formado y ser rechazado por el receptor; y ninguno inválido sintácticamente llegará siquiera a la fase de validación de esquema.
Los cinco errores de sintaxis más frecuentes
Uno: el ampersand suelto. Una URL con ?a=1&b=2 dentro de un elemento rompe el documento; debe ser &b=2 o ir dentro de CDATA. Dos: etiquetas mal anidadas, típico al generar XML concatenando cadenas. Tres: más de un elemento raíz, habitual al concatenar dos respuestas. Cuatro: caracteres de control no permitidos (los bytes 0x00-0x08 y 0x0B-0x0C son ilegales incluso escapados), que suelen colarse desde una base de datos con datos sucios. Cinco: la declaración <?xml ... ?> precedida de un espacio, un BOM o una línea en blanco, que provoca el error "content is not allowed in prolog".
Codificación declarada frente a codificación real
El atributo encoding de la declaración XML es una afirmación, no una conversión: si el fichero está en ISO-8859-1 y declara UTF-8, el parser fallará en la primera eñe con un error de byte inválido. Cuando recibas un fichero de un sistema antiguo, comprueba con file -i documento.xml cuál es la codificación real y conviértela con iconv antes de procesar, o corrige la declaración. El BOM de UTF-8 es tolerado por la mayoría de parsers, pero cualquier byte anterior a él no lo es.
Validar contra XSD en la línea de comandos
El navegador no valida contra esquema, pero xmllint sí y viene en casi todas las distribuciones dentro del paquete libxml2-utils. xmllint --noout --schema esquema.xsd documento.xml devuelve el listado de incumplimientos con línea exacta; xmllint --noout documento.xml comprueba sólo que esté bien formado, y xmllint --format lo reindenta para poder leerlo. Es el flujo estándar antes de enviar un fichero de facturación electrónica o un mensaje SEPA, porque el receptor aplicará exactamente esa validación.
Riesgos de seguridad al parsear XML ajeno
Dos ataques clásicos siguen vivos. XXE (XML External Entity) abusa de las entidades externas para leer ficheros del servidor (/etc/passwd) o hacer peticiones desde él: la mitigación es desactivar la resolución de entidades externas y DTD en el parser, algo que muchas librerías ya hacen por defecto pero que otras no. La "billion laughs" define entidades anidadas que se expanden exponencialmente hasta agotar la memoria; se mitiga limitando la expansión de entidades. Si tu servicio recibe XML de terceros, revisa la configuración del parser antes que ninguna otra cosa. El DOMParser del navegador que usa esta herramienta no resuelve entidades externas.
Herramientas complementarias del flujo
Una vez el documento es válido, lo habitual es transformarlo o consumirlo: xmllint --xpath extrae nodos concretos sin escribir código, XSLT transforma a otro formato y el conversor JSON ↔ XML del sitio te da una vista en JSON mucho más cómoda para inspeccionar a ojo. Si el problema está en un fragmento que debe incrustarse dentro de HTML, la herramienta de codificación HTML te muestra cómo debe quedar escapado.
Casos de uso comunes
- Localizar la línea exacta que rompe una factura electrónica rechazada.
- Comprobar un sitemap XML antes de enviarlo a Search Console.
- Verificar la respuesta de un servicio SOAP que falla sin mensaje claro.
- Revisar un fichero de configuración XML tras editarlo a mano.
- Validar un feed RSS antes de publicarlo.
Buenas prácticas
- Escapa siempre `&` y `<` en el contenido, o encierra el texto en `CDATA`.
- Asegúrate de que la codificación declarada coincide con la real.
- Valida contra el XSD del receptor con `xmllint` antes de enviar.
- Desactiva entidades externas y DTD al parsear XML de terceros.