Anteriormente vimos como leer datos y escribir datos en un archivo XML. Ahora vamos a mostrar como insertar un nodo o registro en cualquier lugar del árbol de nodos del archivo XML.
Aunque comenzaremos viendo como insertar un nodo al final de un archivo, que es la operación más habitual, luego veremos como insertar un registro de forma más controlada.
Dado que las clases que vamos a utilizar para este ejemplo ya fuerón explicadas anteriormente recomiendo a todo el mundo que lean en primer lugar los artículos precedentes. Además el modelo de archivo XML es el mismo que en los ejemplos anteriores.
En primer lugar crearemos el nodo que deseamos insertar.
private XmlNode CrearNodoXml(string id, string nom, string ape, string nss, string fijo, string mvl)
{
//Creamos el nodo que deseamos insertar.
XmlElement empleado = documento.CreateElement("empleado");
//Creamos el elemento idEmpleado.
XmlElement idEmpleado = documento.CreateElement("idEmpleado");
idEmpleado.InnerText = id;
empleado.AppendChild(idEmpleado);
//Creamos el elemento nombre.
XmlElement nombre = documento.CreateElement("nombre");
nombre.InnerText = nom;
empleado.AppendChild(nombre);
//Creamos el elemento apellidos.
XmlElement apellidos = documento.CreateElement("apellidos");
apellidos.InnerText = ape;
empleado.AppendChild(apellidos);
//Creamos el elemento numeroSS.
XmlElement numeroSS = documento.CreateElement("numeroSS");
numeroSS.InnerText = nss;
empleado.AppendChild(numeroSS);
//Creamos el elemento telefonos.
XmlElement telefonos = documento.CreateElement("telefonos");
empleado.AppendChild(telefonos);
//Creamos el elemento fijo.
XmlElement nodoFijo = documento.CreateElement("fijo");
nodoFijo.InnerText = fijo;
telefonos.AppendChild(nodoFijo);
//Creamos el elemento movil.
XmlElement movil = documento.CreateElement("movil");
movil.InnerText = mvl;
telefonos.AppendChild(movil);
return empleado;
}
Una vez que tenemos el nodo creado procedemos a insertar un registro al final del documento XML.
private void InsertarXml()
{
//Cargamos el documento XML.
documento = new XmlDocument();
documento.Load(ruta);
//Creamos el nodo que deseamos insertar.
XmlNode empleado = this.CrearNodoXml("4", "Gerardo", "Montaz Soaz", "444-444-444-444", "893434220", "609334209");
//Obtenemos el nodo raiz del documento.
XmlNode nodoRaiz = documento.DocumentElement;
//Insertamos el nodo empleado al final del archivo
nodoRaiz.InsertAfter(empleado, nodoRaiz.LastChild); //***
documento.Save(ruta);
}
Ahora nos fijamos en la función anterior justo en la linea que esta marcada con //*** . Esta linea es la que inserta el nodo precisamente a
continuación del último nodo del documento XML. Como hemos comentado antes esta es la operación más usual pero existen más opciones.
- Insertar antes del último nodo del documento.
nodoRaiz.InsertBefore(empleado, nodoRaiz.LastChild);
- Insertar después del primer nodo del documento.
nodoRaiz.InsertAfter(empleado, nodoRaiz.FirstChild);
- Insertar antes del primer nodo del documento.
nodoRaiz.InsertBefore(empleado, nodoRaiz.FirstChild);
- Insertar en un lugar determinado del documento.
nodoRaiz.InsertAfter(empleado, documento.SelectNodes("empleados/empleado").Item(2));
En este último caso hay que tener en cuenta que el método Item() accede a la colección de nodos del documento, y esta colección tiene
un índice inicial igual acero. En el ejemplo, hemos insertado el nodo después del elemento 2 de la colección, pero podíamos haberlo insertado
antes con InsertBefore().
Vamos arrojar un poco de luz sobre las diferencias entre utilizar el método Parse() de las estructuras de tipos de .NET o utilizar los métodos de la clase System.Convert. En realidad parece que hacen lo mismo pero existe una gran diferencia.
Suponamos que dejamos que un usuario introduzca un valor númerico por pantalla y queremos realizar calculos con ese valor. Por lo tanto, el valor introducido por el usuario será del tipo System.String y deberemos convertirlo a un tipo de valor numérico, por ejemplo System.Int32.
En definitiva queremos saber que diferencia hay entre ejecutar estas dos lineas de código:
int valorA = Convert.ToInt32(valorUsuario);
int valorB = Int32.Parse(valorUsuario);
Cuando utilizamos la segunda opción, el método Parse(), si el usuario no ha introducido ningún valor (null) recibiremos una excepción del tipo System.FormatException. Lo que indica que el formato del argumento no cumple las especificaciones del parámetro del método invocado.
En cambio, cuando utilizamos la primera opción, los métodos de la clase System.Convert, si el valor pasádo al método es null, el método ConovertToInt32() devolverá un valor numérico, devolverá cero en todos los casos que el valor de entrada sea null.
Utilizando la herramienta Reflector podemos ver las diferencias de código que hay entre estas dos formas de convertir los tipos de .NET.
public static int ToInt32(string value)
{
if (value == null)
{
return 0;
}
return int.Parse(value, CultureInfo.CurrentCulture);
}
public static int Parse(string s)
{
return Number.ParseInt32(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}
Cuando se establece el seguimiento (o trazas) de una página ASP.NET, se agregan a la página unas tablas con detalles de ejecución de la solicitud de la página. El seguimiento se puede establecer a una página individualmente como veremos a continuación.
Dado que el seguimiento de forma predeterminada esta deshabilitado, para activarlo hay que establecer a true el atributo Trace de la directiva @Page de la página en cuestión.
<% @Page Trace = "true" %>
Por seguridad hay que tener en cuenta, a la hora de subir nuestra aplicación a un servidor de producción, que el seguimiento debe estar deshabilitado ya que el seguimiento muestra datos confidenciales de la aplicación y del servidor.
Mediante el atributo traceMode podemos especificar el orden en que aparecen los mensajes de seguimiento. Este atributo tiene dos valores:
- SortByTime. La información de seguimiento se muestra en el orden que se procesó.
- SortByCategory. La información de seguimiento se muestra por orden alfabético de las categorías definidas por el usuario.
<% @Page Trace = "true" traceMode="SortByCategory" %>
También se puede establecer el seguimiento en el archivo Web.config de nuestra aplicación. Para ello solo hay que establecer a true los atributos enabled, localOnly y pageOutput del elemento trace.
<configuration>
<system.web>
<trace enabled="true" localOnly="true" pageOutput="true" traceMode="SortByCategory" />
</system.web>
</configuration>
A continuación podéis ver la información de seguimiento de una típica página "Hello World".
Detalles de la solicitud |
| Id. de sesión: | so5sh245ipug3sfs2qez4j55 | Tipo de petición: | GET |
| Hora de la solicitud: | 08/04/2009 9:51:52 | Código de estado: | 200 |
| Codificación de la solicitud: | Unicode (UTF-8) | Codificación de la respuesta: | Unicode (UTF-8) |
Información de seguimiento |
| Categoría | Mensaje | Desde los primeros | Desde los últimos |
| aspx.page | Begin PreInit | | |
| aspx.page | End PreInit | 1,96441227757674E-05 | 0,000020 |
| aspx.page | Begin Init | 6,1746385914912E-05 | 0,000042 |
| aspx.page | End Init | 9,30005812536328E-05 | 0,000031 |
| aspx.page | Begin InitComplete | 0,000103578647366546 | 0,000011 |
| aspx.page | End InitComplete | 0,00011290870567941 | 0,000009 |
| aspx.page | Begin PreLoad | 0,000122217763861024 | 0,000009 |
| aspx.page | End PreLoad | 0,000133389833686461 | 0,000011 |
| aspx.page | Begin Load | 0,000142401890011813 | 0,000009 |
| aspx.page | End Load | 0,000255985599909999 | 0,000114 |
| aspx.page | Begin LoadComplete | 0,000269248682804268 | 0,000013 |
| aspx.page | End LoadComplete | 0,000278818742617141 | 0,000010 |
| aspx.page | Begin PreRender | 0,000290539815873849 | 0,000012 |
| aspx.page | End PreRender | 0,000309385933662085 | 0,000019 |
| aspx.page | Begin PreRenderComplete | 0,000319708998181239 | 0,000010 |
| aspx.page | End PreRenderComplete | 0,000328859055369096 | 0,000009 |
| aspx.page | Begin SaveState | 0,000803153019706373 | 0,000474 |
| aspx.page | End SaveState | 0,00226603416271352 | 0,001463 |
| aspx.page | Begin SaveStateComplete | 0,00228027225170157 | 0,000014 |
| aspx.page | End SaveStateComplete | 0,0022899113119457 | 0,000010 |
| aspx.page | Begin Render | 0,00229895936849605 | 0,000009 |
| aspx.page | End Render | 0,0033112676954231 | 0,001012 |
Árbol de control |
| UniqueID de control | Tipo | Bytes del tamaño del proceso (incluidos secundarios) | Tamaño en bytes de ViewState (sin elementos secundarios) | Bytes de tamaño de ControlState (excluidos secundarios) |
| __Page | ASP.default_aspx | 595 | 0 | 0 |
| ctl02 | System.Web.UI.LiteralControl | 174 | 0 | 0 |
| ctl00 | System.Web.UI.HtmlControls.HtmlHead | 52 | 0 | 0 |
| ctl01 | System.Web.UI.HtmlControls.HtmlTitle | 39 | 0 | 0 |
| ctl03 | System.Web.UI.LiteralControl | 14 | 0 | 0 |
| form1 | System.Web.UI.HtmlControls.HtmlForm | 335 | 0 | 0 |
| ctl04 | System.Web.UI.LiteralControl | 21 | 0 | 0 |
| Label1 | System.Web.UI.WebControls.Label | 36 | 36 | 0 |
| ctl05 | System.Web.UI.LiteralControl | 18 | 0 | 0 |
| ctl06 | System.Web.UI.LiteralControl | 20 | 0 | 0 |
Estado de la sesión |
| Clave de sesión | Tipo | Valor |
Estado de la aplicación |
| Clave de aplicación | Tipo | Valor |
Colección de cookies de solicitud |
| Nombre | Valor | Tamaño |
Colección de cookies de respuesta |
| Nombre | Valor | Tamaño |
Colección de encabezados |
| Nombre | Valor |
| Connection | Keep-Alive |
| Accept | */* |
| Accept-Encoding | gzip, deflate |
| Accept-Language | es |
| Host | localhost:2037 |
| User-Agent | Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; GTB5; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; OfficeLiveConnector.1.3; OfficeLivePatch.0.0) |
Colección de encabezados de respuesta |
| Nombre | Valor |
| X-AspNet-Version | 2.0.50727 |
| Cache-Control | private |
| Content-Type | text/html |
Colección de formularios |
| Nombre | Valor |
Colección de cadenas de consulta |
| Nombre | Valor |
Variables del servidor |
| Nombre | Valor |
| ALL_HTTP | HTTP_CONNECTION:Keep-Alive HTTP_ACCEPT:*/* HTTP_ACCEPT_ENCODING:gzip, deflate HTTP_ACCEPT_LANGUAGE:es HTTP_HOST:localhost:2037 HTTP_USER_AGENT:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; GTB5; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; OfficeLiveConnector.1.3; OfficeLivePatch.0.0) |
| ALL_RAW | Connection: Keep-Alive Accept: */* Accept-Encoding: gzip, deflate Accept-Language: es Host: localhost:2037 User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; GTB5; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; OfficeLiveConnector.1.3; OfficeLivePatch.0.0) |
| APPL_MD_PATH | |
| APPL_PHYSICAL_PATH | C:\Documents and Settings\oscar.sotorrio\Mis documentos\Visual Studio 2008\WebSites\HelloWorld\ |
| AUTH_TYPE | NTLM |
| AUTH_USER | INECO\oscar.sotorrio |
| AUTH_PASSWORD | |
| LOGON_USER | INECO\oscar.sotorrio |
| REMOTE_USER | INECO\oscar.sotorrio |
| CERT_COOKIE | |
| CERT_FLAGS | |
| CERT_ISSUER | |
| CERT_KEYSIZE | |
| CERT_SECRETKEYSIZE | |
| CERT_SERIALNUMBER | |
| CERT_SERVER_ISSUER | |
| CERT_SERVER_SUBJECT | |
| CERT_SUBJECT | |
| CONTENT_LENGTH | 0 |
| CONTENT_TYPE | |
| GATEWAY_INTERFACE | |
| HTTPS | |
| HTTPS_KEYSIZE | |
| HTTPS_SECRETKEYSIZE | |
| HTTPS_SERVER_ISSUER | |
| HTTPS_SERVER_SUBJECT | |
| INSTANCE_ID | |
| INSTANCE_META_PATH | |
| LOCAL_ADDR | 127.0.0.1 |
| PATH_INFO | /HelloWorld/Default.aspx |
| PATH_TRANSLATED | C:\Documents and Settings\oscar.sotorrio\Mis documentos\Visual Studio 2008\WebSites\HelloWorld\Default.aspx |
| QUERY_STRING | |
| REMOTE_ADDR | 127.0.0.1 |
| REMOTE_HOST | 127.0.0.1 |
| REMOTE_PORT | |
| REQUEST_METHOD | GET |
| SCRIPT_NAME | /HelloWorld/Default.aspx |
| SERVER_NAME | localhost |
| SERVER_PORT | 2037 |
| SERVER_PORT_SECURE | 0 |
| SERVER_PROTOCOL | HTTP/1.1 |
| SERVER_SOFTWARE | |
| URL | /HelloWorld/Default.aspx |
| HTTP_CONNECTION | Keep-Alive |
| HTTP_ACCEPT | */* |
| HTTP_ACCEPT_ENCODING | gzip, deflate |
| HTTP_ACCEPT_LANGUAGE | es |
| HTTP_HOST | localhost:2037 |
| HTTP_USER_AGENT | Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; GTB5; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; OfficeLiveConnector.1.3; OfficeLivePatch.0.0) |
Versión de Microsoft .NET Framework:2.0.50727.1433; Versión ASP.NET:2.0.50727.1433
Podéis ver el significado de la información de seguimiento
aquí.