Thinking in SharePoint

Blog sobre desarrollo en la plataforma .Net, centrado en Silverlight y SharePoint

Hay ocasiones en las que tenemos que leer información que se nos proporciona a través de un XML, los motivos pueden ser muy diversos, pero siempre se nos plantea un problema: ¿Cómo asegurarnos de que el archivo que leemos tiene la estructura deseada?

La respuesta es clara: validando el documento contra una DTD.

La plataforma .Net nos proporciona métodos sencillos para ello, siempre que la DTD se encuentre incluida en el mismo, o que al menos el documento incluya la cabecera

<DOCTYPE NombreDoc SYSTEM "NombreDTD.dtd">

donde se referencia al archivo que contiene la dtd. Por ejemplo, aquí nos dice Microsoft cómo hacerlo.

Pero en ocasiones estos xml deben ser proporcionados o modificados por usuarios o personal técnico no experto.

Máxima de la programación:
No podemos fiarnos de que los datos proporcionados por el usuario sean correctos
Así que vamos a facilitarles la vida, ellos modificarán o escribirán el xml, y nosotros nos encargamos de validarlo contra una dtd propia.

Si nuestra dtd se encontrara en un archivo externo, podríamos optar por la opción de añadir la linea DOCTYPE en la cabecera si no la tiene, y volver a leer el documento.

Yo propongo un método que valida un documento a partir de una dtd dada en un string devolviendo el XmlDocument resultante.

Es un método que uso frecuentemente en el desarrollo web (Ya sabéis que hacemos las mejores intranets con SharePoint), por lo que la ubicación del archivo a validar se introduce como una url relativa al servidor.

El código de la función tendría el siguiente aspecto (lo comento sobre la marcha):

private
XmlDocument LoadAndValidateXML(string dtd, string urlXML)
{
//Devolveremos null si no existe
XmlDocument
xmlDoc
= null;

if (File.Exists(MapPathSecure(urlXML)))
{
//Leemos el archivo como una cadena a la que añadimos nuestra dtd
StreamReader sr = new StreamReader(MapPathSecure(urlXML));
string xmlString = sr.ReadToEnd();
xmlString = dtd + xmlString;

//Preparamos las opciones necesarias para la validación
XmlReaderSettings xmlSettings = new XmlReaderSettings();
xmlSettings.ValidationType = ValidationType.DTD;
xmlSettings.ProhibitDtd = false;
xmlSettings.NameTable = new NameTable();

//Preparamos la lectura del string como xml con las opciones anteriores
StringReader
input = new StringReader(xmlString);
XmlTextReader reader = new XmlTextReader(input);
XmlReader xmlReader = XmlReader.Create(reader, xmlSettings);

//Creamos el XmlDocument que contendrá el resultado en caso positivo
xmlDoc
= new XmlDocument();

try
{
//Intentamos validar
xmlDoc.Load(xmlReader);
}
catch (Exception ex)
{
//Devolveremos null si algo ha ido mal
xmlDoc = null;

//Tratar aquí la excepción
}
finally
{
//Siempre cerramos el stream
xmlReader.Close();
}

}
return xmlDoc;

}


Por último sólo me queda recordaros que este método sólo valida que el documento tenga la estructura que nosotros queremos, pero NO valida los datos incluidos, por lo que siempre deberemos tomar las medidas de seguridad adecuadas para tratar la entrada de datos del usuario.

0 comentarios:

Publicar un comentario