27 de mayo de 2015

Jquery Validate

Para comenzar a utilizar jquery.validation, simplemente debemos agregar una referencia a las librerías jQuery y jquery.validation en nuestra página, en mi caso utilizare CDN para ambas librerías, aquí un primer ejemplo
  



  


Formulario de Registro

First Name
Last Name
Email
Password
Puedes ejecutar el script anterior tal como esta pero si quiere ver un cambio en el color de los mensajes de error te dejo este css
.label {
  width:100px;
  text-align:right;
  float:left;
  padding-right:10px;
  font-weight:bold;
}

#register-form label.error {
  color:#FB3A3A;
  font-weight:bold;
}

h1 {
  font-family: Helvetica;
  font-weight: 100;
  color:#333;
  padding-bottom:20px;
}

El método .validate() valida los campos de y si todos los campos son correctos enviará el formulario pero en caso no queramos enviar el formulario sino solamente necesitamos saber si el formulario está validado entonces cambiaremos el método .validate() por .valid(), el cual nos devolverá true o false dependiendo de si el formulario está correcto o no, y lo comprobaremos con un evento .click().

$("#enviar").click(function(){
  var validado = $("#formulario").valid();
    if(validado){
      alert('El formulario es correcto.');
       }
    });

Jquery Validate por defecto valida que los campos no estén vacíos (required), ¿pero si queremos validar un email o un máximo número de caracteres para un nombre?, pues para eso podemos usar el método rules de Jquery Validate, ¿y como? bueno simplemente agregando los métodos necesarios para ese campo o campos (que pueden ser required, email, max, min, range , etc…).

submitHandler: function(form) - invalidHandler: function(form)
La función submitHandler captura el evento action del formulario validado y define las acciones a seguir en caso el formulario sea valido y la función invalidHandler se activa cuando el formulario no pasa las validaciones y define las acciones a seguir, en caso quisiéramos utilizar AJAX para llamadas asincrónicas podemos utilizar como ejemplo el siguiente código

Mensajes de error
Cuando sucede un error durante la validación, por defecto jquery.validation agrega dinámicamente una etiqueta label a continuación del campo validado. Además, el mensaje de esta etiqueta es igualmente predefinido y está en inglés pero en la misma descarga del plugin hay una carpeta localization donde están todos los ficheros de idioma, si por ejemplo, queremos los mensajes en español bastaría con incluir la siguiente referencia a nuestra página, siempre después de la referencia a jquery.validation.

El contenido de este fichero es el siguiente:
/*
 * Translated default messages for the jQuery validation plugin.
 * Locale: ES
 */
jQuery.extend(jQuery.validator.messages, {
  required: "Este campo es obligatorio.",
  remote: "Por favor, rellena este campo.",
  email: "Por favor, escribe una dirección de correo válida",
  url: "Por favor, escribe una URL válida.",
  date: "Por favor, escribe una fecha válida.",
  dateISO: "Por favor, escribe una fecha (ISO) válida.",
  number: "Por favor, escribe un número entero válido.",
  digits: "Por favor, escribe sólo dígitos.",
  creditcard: "Por favor, escribe un número de tarjeta válido.",
  equalTo: "Por favor, escribe el mismo valor de nuevo.",
  accept: "Por favor, escribe un valor con una extensión aceptada.",
  maxlength: jQuery.validator.format("Por favor, no escribas más de {0} caracteres."),
  minlength: jQuery.validator.format("Por favor, no escribas menos de {0} caracteres."),
  rangelength: jQuery.validator.format("Por favor, escribe un valor entre {0} y {1} caracteres."),
  range: jQuery.validator.format("Por favor, escribe un valor entre {0} y {1}."),
  max: jQuery.validator.format("Por favor, escribe un valor menor o igual a {0}."),
  min: jQuery.validator.format("Por favor, escribe un valor mayor o igual a {0}.")
});

Personalizando los mensajes de error
Los mensajes de error se muestran por defecto a continuación del campo erróneo. Aparecen dentro de la etiqueta

errorContainer(): especifica un contenedor a usar para mostrar los mensajes.error.
LabelContainer(): contiene los errores en una lista desordenada, esta lista desordenada va dentro de un errorcontainer y para mostrarla se puede utilizar wrapper: "li".
errorElement(): permite definir el elemento html que contendrá el texto del mensaje a mostrar.
wrapper(): envuelve la etiqueta definida en errorElement dentro de la que especifiquemos.

Ejemplo de uso
$('form').validate({
    errorContainer: "#messageBox1",
    errorLabelContainer: "#messageBox1 ul",
    wrapper: "li"
});
Es equivalente a
  • Field is required
  • Enter a valid email
Otros elementos a tomar en cuenta:
Con ignore podemos especificar un selector jQuery para ignorar campos de nuestro formulario.
onsubmit, onfocus, onkeyup, onclick nos permiten decidir cuándo se realizará la validación.
Con errorClass y validClass podemos especificar el nombre de la clase CSS que se agregará al elemento validado en caso de fracaso o de éxito de la validación.
errorPlacement es una función que nos permite decidir donde situar los mensajes de error generados, errorPlacement vendría a ser el competidor de errorContainer.
higlight y unhiglight determinan como resaltar los elementos que no han superado la validación.

Aquí un ejemplo de uso de higlight y unhiglight
    El css
    label.error{
     color: Red;
    }
    
    input.highlight {
     outline: none;
     border-color: #ff0000;
     box-shadow: 0 0 10px #800000;
    }
    
    Y el javascript
    $('form').on('submit', false);
    
    $('#btSubmit').click(function(){
       $('#myForm').valid();
    });
    
    $('#myForm').validate({
       rules: {
        firstName: "required",
        lastName: {
          required: true,
          atLeastXCharacters: { 
          fieldDescription: "Last Name",
          minCharacters: 5
                }
            }
        },
       messages:{
        firstName: {
          required: "First name is required"
            },
        lastName: {
          required: "Last name is required"
            }
        },
     
       errorLabelContainer: '#listOfErrors',
        wrapper: 'li', 
        highlight: function(element, errorClass, validClass){
            $(element).addClass("highlight");
        },
    
        unhighlight: function(element, errorClass, validClass){
            $(element).removeClass("highlight");
        }
    });
    
    $.validator.addMethod("atLeastXCharacters", function(value, element, params){
        return value.length > params.minCharacters;
    }, function(params, element){
        return $.format("{0} needs at least {1} characters", params.fieldDescription, params.minCharacters);
    });
    

    Aquí un ejemplo de uso de errorElement con ErrorContainer
    $(document).ready(function() { 
    $("#commentForm").validate ( {
       
     showErrors: function(errorMap, errorList) {
       $("#warning").html("Tu formulario contiene " + this.numberOfInvalids() + " errores.");
       this.defaultShowErrors();
              },
        debug: false,
        errorElement: "em",
        errorContainer: $("#warning"),
        success: function(label) {
        label.text("ok!").addClass("success");
         }
      }); 
    });
    
    Aquí un ejemplo de uso de errorElement con ErrorPlacement
    Y el codigo javascript
    $(function(){
    $("#form").validate({
     messages: {
       name: "Please enter name.",
       surname: "Please enter surname."    
        },
    
     errorElement: "span",   
     errorPlacement: function(error, element) {
       error.insertAfter(element);
            }   
    });
    });
    
    Aquí un ejemplo de uso de errorElement con ErrorPlacement para varios tipos de input
    Y el código javascript
    errorElement: 'span',
      errorPlacement: function (error, element) {
        var type = $(element).attr("type");
          if (type === "radio") {
            // custom placement
            error.insertAfter(element).wrap('
  • '); } else if (type === "checkbox") { // custom placement error.insertAfter(element).wrap('
  • '); } else { error.insertAfter(element).wrap('
    '); } },
    • Un ejemplo con errorContainer-ErrorlabelContainer y Wrapper
      
      
        Move Validation Warnings
        
        
      
      
      
      Please correct the following errors and try again:
      Y el css
      body {
       font-family: Georgia, "Times New Roman", Times, Serif;
       padding: 1em;
       background-color: #F2F2F2;
      }
      
      h2 {
       border-bottom: 1px solid #DDD;
      }
      
      div {
       background-color: #FFF;
       border: 1px solid #A8A8A8;
       padding: 0.5em;
       margin-bottom: 1em;
      }
      
      input {
       font-family: Georgia, "Times New Roman", Times, Serif;
      }
      
      label {
        width: 10em;
        float: left;
      }
      
      p {
        clear: both;
      }
      
      #errorContainer {
        display: none;
        overflow: auto;
        background-color: #FFDDDD;
        border: 1px solid #FF2323;
        padding-top: 0;
      }
      
      #errorContainer label {
        float: none;
        width: auto;
      }
      

    12 de mayo de 2015

    Buscador PHP Jquery AJAX JSON

    Para ejemplificar el uso de las tecnologias PHP-Jquery-AJAX-JSON se muestra la codificación de un buscador realizado en PHP que utiliza Jquery con su metodo $.ajax para hacer peticiones asincrónicas sobre una base de datos MySQL y que recibe un resultado especifico en formato JSON, este resultado es mostrado al usuario en un div ubicado en la pagina buscador.php.

    Primero muestro el script de la tabla empleado_php
    USE `ejemplo`;
    
    DROP TABLE IF EXISTS `empleado_php`;
    
    CREATE TABLE `empleado_php` (
      `ID` varchar(8) NOT NULL,
      `Nombre` varchar(50) DEFAULT NULL,
      `cargo` varchar(50) DEFAULT NULL,
      PRIMARY KEY (`ID`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
    insert  into `empleado_php`(`ID`,`Nombre`,`cargo`) values 
    ('PHP001','Pablo Ernesto Tobar Mayora','Web Programmer'),
    ('PHP002','Pabletoreto Blogger','Blogger Manager'),
    ('PHP003','prueba de stored procedure en MySQL','Database Administrator'),
    ('PHP004','Prueba de funciones en MySQL','Database Tester');
    
    Para evitar confusión quiero hacer notar que siempre codifico los formularios con extensión php aunque como pueden ver en el código no se utiliza mas que HTML por ende el formulario buscador puede tener extensión PHP(buscador.php) o bien extensión HTML(buscador.html)
    <?php
    //html lang="es-ES"
    //head
    
    
    
    
    BUSCADOR
    //head
    
    
    Buscador Asincrono ID a buscar:

    Datos empleado seran mostrados aqui...
    Lo importante comienza con especificar el lenguaje de nuestro formulario y la declaración de una directiva pragma en la etiqueta head del formulario a fin de codificar los caracteres que se enviaran, también es importante notar que se agrega la libreria Jquery en la etiqueta script del documento así como también un documento javascript llamado jquery,js ubicado en la carpeta javascript que realizara la petición asincronica,para terminar se utilizara una hoja de estilos llamada estilos.css ubicada en la carpeta content.

    Se muestra el código de jquery.js en este se evita que se envíe el formulario a su action="process.php", en vez de eso, se toma el dato de búsqueda y se valida que no este vacío en la función validaForm(), como solo se tiene un dato solo se valida que exista (pero las validaciones en un formulario pueden ser mas complejas) para luego tomar el valor y enviarlo a process.php utilizando el método $.ajax()
    $(document).ready(function() {
      $("#form_id").submit(function(e){
        e.preventDefault(); 
     preparar();
         if(validaForm()){  
        requestInfo();
     }
         else {return ; }  
      });
    });
    
    function preparar(){
      $("#submit_id").hide();
      $("#ajax_id").html("");
      $("#LoadingImage").show();
      $("#ajax_id").html("
    realizando busqueda
    "); } function validaForm(){ var id_val = $("input#ID_id").val().trim(); if((id_val=="") || id_val.replace(/s+/,'') == ''){ alert("Favor ingrese el ID"); $("input#ID_id").addClass("posicionamiento"); $("#ajax_id").html("
    Debe especificar el nombre
    "); return false; }else{ $("input#ID_id").removeClass("posicionamiento"); $("#div_id").empty(); } return true; } function requestInfo(){ var url = $("#form_id").attr('action'); var data = $("#form_id").serialize(); var type = $("#form_id").attr('method'); $.ajax({ url:url, data:data, type:type, cache: false, contentType: "application/x-www-form-urlencoded", dataType: 'json', encode: true, }) .done(function(data) { if(data.status != "ERROR"){ $("#infoemp tbody").html(""); $("#ajax_id").html(""); $("#submit_id").show(); $("#LoadingImage").remove(); if(data.total > 0){ $("#ajax_id").html("
    " +data.total+ "
    "); $("#infoemp").show(); $.each(data.info, function(i,user){ var tblRow = "" +""+user.ID+" " +""+user.Nombre+" " +""+user.cargo+" " +"" ; $(tblRow).appendTo("#infoemp tbody"); }); } else { $("#ajax_id").html("
    No se encontraron resultados
    "); } } else { alert("lee .......... ERROR"); $("#LoadingImage").remove(); $("#ajax_id").html(""); $("#ajax_id").html(data.error_msg).addClass("cargando"); } }) .fail(function( jqXHR, textStatus, errorThrown ) { // if ( console && console.log ) { //console.log( "La solicitud a fallado: " + errorThrown); } $("#LoadingImage").remove(); $("#ajax_id").html(""); $("#submit_id").show(); alert( "La solicitud a fallado: " + errorThrown); //} }); }
    en caso no quieras serializar la información directamente del formulario sino crearla por tu cuenta e incluso agregar mas información puedes utilizar un array de la siguiente manera
     var array = new Object(); 
      array['tag'] = "login";
      array['usuario'] = $("#user").val(); 
      array['password'] = $.md5($("#pass1").val()); 
    
    el código de process.php se encarga de conectarse a la base de datos utilizando mysqli y buscar el registro especifico
    <?php
    mysqli_report(MYSQLI_REPORT_STRICT);
    
    $bd = "ejemplo";
    $server ="localhost";
    $user = "root";
    $password = "";
    
    if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    
     $var = array (
      "status" => "",        // "OK "| "FALSE"
      "total" => intval(0),  // total de registros encontrados
      "info" => "",          // registros encontrados
      "error_msg" => ""      // mensaje de error
         );
    
     if (isset($_POST['ID_name'])) {
      $valor = filter_var($_POST['ID_name'], FILTER_SANITIZE_STRING);
        
     if(empty($valor)){
      $var["status"]="ERROR";
      $var["error_msg"]="Debe especificar el ID"; 
     }
    
     try {
    
      $mysqli = mysqli_connect($server, $user, $password, $bd);
      $prepared_st = $mysqli->prepare("SELECT * FROM empleado_php WHERE ID = ?");
      $prepared_st->bind_param("s",$valor);
      $prepared_st->execute();
        
       $var["status"]="OK";
       $result = $prepared_st->get_result();  
        if($result->num_rows>0){   
         $var["total"]=$result->num_rows;
          while($obj = mysqli_fetch_assoc($result)) {
           $var["info"][] = array_map('utf8_encode', $obj);
           //$var["info"][] = $obj;
        }
       }
    
     else { $var['total']=0; }
      
       $result->close();
       $mysqli->close(); 
    
     } catch (Exception $e ) {
       $var["status"]="ERROR";
       $var["error_msg"]="message: " . $e->message;  
     }
       
    header('Content-type: application/json; charset=utf-8');   
    echo json_encode($var);
    exit();
    }
    else
    header('Location: http://localhost:8080/buscador/buscador.php');
    }
    else
    header('Location: http://localhost:8080/buscador/buscador.php'); 
    ?>
    
    por ultimo el código de estilos.css
    label {
    display:block;
    margin-top:20px;
    letter-spacing:1px;
    }
    
    form {
    display:block;
    margin:0 auto;
    width:400px;
    font-family:Arial;
    color: #666666;
    }
    
    .posicionamiento{
        border:2px solid red;
     color:black;
     background-color:white;
     width:350px;
        font-size:16px;
    }
    
    input, textarea {
    width:350px;
    height:40px;
    background:#666666;
    border:2px solid #f6f6f6;
    padding:10px;
    margin-top:3px;
    font-size:15px;
    color:#ffffff;
    }
    
    #submit_id {
    width:85px;
    height:35px;
    border:none;
    margin-top:20px;
    cursor:pointer;
    }
    
    .info, .exito, .alerta, .error { 
           text-align:center;
           width: 330px;
           font-family:Arial, Helvetica, sans-serif;  
           font-size:13px; 
           border: 1px solid; 
           margin: 0 auto; 
           padding:15px 10px 15px 50px; 
           background-repeat: no-repeat; 
           background-position: 10px center; 
    } 
    .info { 
           color: #00529B; 
           background-color: #BDE5F8; 
           background-image: url('imagenes/info.png'); 
    } 
    .exito { 
           color: #4F8A10; 
           background-color: #DFF2BF; 
           background-image:url('imagenes/exito.png'); 
    } 
    .alerta { 
           color: #9F6000; 
           background-color: #FEEFB3; 
           background-image: url('imagenes/alerta.png'); 
    } 
    .error { 
           margin:0 auto;
        width:250px;
        color: #D8000C; 
           background-color: #FFBABA; 
           background-image: url('imagenes/error_.png'); 
    } 
    
    .cargando{
    margin:0 auto;
    width:250px;
        color: #D8000C; 
           background-color: white; 
           background-image: url('imagenes/cargando.gif');
    }
    
    y las imágenes utilizadas

    Resaltar sintaxis PHP en navegadores

    A veces debes mostrar tu código php en el navegador de tu red interna para que otras personas puedan revisarlo y crear un complemento a codificar un modulo que implemente tu función, que herede de tu clase, que utilice tu interfaz, etc

    Ante estos casos por seguridad no les envías tu archivo php ya que la persona interesada solo necesita saber cual fue la lógica con que trabajaste tu código, para solo mostrar tu código con la sintaxis php correcta puedes utilizar esta función siempre teniendo en cuenta de especificar correctamente la ruta donde esta guardado tu archivo php
    <?php
    echo nl2br(highlight_string(file_get_contents('BLOGGER\CFG\parametros.php')));
    ?>
    

    Buscador PHP utilizando MySQLi

    Antes de empezar hago la acotación que este es un ejemplo básico pero que aun se utiliza, lo mejor seria utilizar Jquery para utilizar AJAX y recibir los mensajes vía JSON, también utilizar Jquery Validate para el campo obligatorio que en este caso es el DUI, pero es una recomendación, si es puro php lo que te interesa te va servir.

    Los parámetros de configuración de la base de datos es una buena practica tenerlos en un archivo php por separado a fin de poder modificarlos de ser necesario, también te puedes crear una archivo .ini, en este caso para el ejemplo se llama parametros.php

    <?php
    define ('cn_host','localhost');
    define ('cn_username','root');
    define ('cn_password','');
    define ('cn_database','ejemplo');
    ?>
    

    Para conectarme a la base de datos utilizo la funcion conectarse() la cual pide los parametros definidos anteriormente y utiliza mysqli, esta funcion devuelve la conexion a la base de datos especificada en parametros.php o un error i no se alcanza la conexion
    <?php
    require_once "parametros.php";
    
     function conectarse(){
     
     $mysql= new mysqli(cn_host, cn_username, cn_password);
     if($mysql->connect_error){
      echo "Error conectandose al servidor de base de datos";
      echo "/n";
      echo $mysql->connect_error;
         exit();
     }
     if(!($mysql->select_db(cn_database))){
      echo "Error al conectarse a la base de datos";
     }
     return $mysql;
    }
    ?>
    

    por ultimo el buscador.php, solo hacer notar que debería existir un formulario que envíe por el método POST la información de ID_name, un ejemplo básico podría ser este

    Buscador PHP - Mysqli ID a buscar:
    Ahora si, el código que realiza la búsqueda en la base de datos según el dui proporcionado
    <?php
    require_once "conexion.php";
    $mysqli = conectarse(); 
    $query="select Nombre from empleado_php where ID=?";
    $dato= trim($_POST['ID_name']);
    $dato = filter_var($dato, FILTER_SANITIZE_STRING);
    if($dato == null){
    echo "debe especificar el valor del DUI a buscar";
    exit(); 
    }
    
    //puede utilizarse try-catch(Exception $e)
     
    if(!($stmt=$mysqli->stmt_init())){
     echo "Error en stmt_init";
     exit();
    }
    if(!($stmt->prepare($query))){
     echo "Error al preparar la consulta";
     exit();
    }
    if(!($stmt->bind_param("s",$dato))){
     echo "Error anexando parametro";
     exit();
    }
    if(!($stmt->execute())){
     echo "Error al ejecutar la consulta";
     exit();
    }
    
    if(!($stmt->bind_result($nombre))){
     echo"Error al anexar resultado";
     exit();
    }
    
    // store_result debe aparecer antes de fetch()
    $stmt->store_result();
    $stmt->fetch();
    $count = $stmt->num_rows();
    
    if($count!=null){
    echo "Se encontraron " .$count. " resultados";
    echo "";
    echo "El dui " .htmlspecialchars($dato). "  pertenece al empleado " .htmlspecialchars($nombre);
    }
    else { echo "no se encontraron resultados para el DUI " .$dato. "."; }
    $stmt->close();
    $mysqli->close();
    ?>
    
    y si recogiéramos mas de un resultado? en ese caso utilizamos un while y mostramos los resultados, como muestres esos resultados depende de ti, en mi caso utilizare una tabla, recuerda que debes anexar este código según lo que necesites al código mostrado anteriormente
    <?php
    require_once "conexion.php";
    error_reporting(E_ALL);
     
    CargarDatos();
    
    function CargarDatos(){ 
    $query= "select * from empleado_php";
    
     try{
     if(!$mysqli = conectarse()){
      die("Error al crear la conexion:  " .$mysqli->connect_error);
     }
     if(!$stmt= $mysqli->query($query)){
        die('Ocurrio un error: [' . $mysqli->error . ']');
    }
     
     if($stmt->num_rows > 0){
     echo "Total de registros:  " .$stmt->num_rows;
        echo "


    "; echo''; while($row = $stmt->fetch_object()) { echo''; } echo '
    ID Nombre
    '.$row->ID.' '.$row->Nombre.'
    '; }else{ echo "No hay resultados"; } }catch(Exception $e){ echo "Error " .$e->getMessage(); }} ?>

    10 de mayo de 2015

    Operaciones sobre XML desde C#

    1. Se utilizara el archivo contactos.xml para las operaciones, primero se filtraran los resultados a mostrar utilizando Linq to xml

    2. Luego se mostrara información especifica del valor de un nodo(no todo el nodo, solo un valor dentro de este), se agregara, modificara y eliminara información dentro de un nodo, ya sea un valor o un atributo.

    3. Por ultimo se muestra como consultar toda la información de un nodo(no solo un valor o atributo de este) como agregar y como eliminar todo un nodo no solo un valor o atributo de este.
    
      
        Juan
        juan@gmail.com
        666666666
        911111111
      
      
        Luis
        luis@gmail.com
        666777777
      
      
        María
        maria@gmail.com
        666888888
        91222222
      
    
    
    Código Linq2 XML para leer Archivo

    Existen varias formas en .NET C# para leer un fichero XML, acá expondremos 2 formas distintas aunque si fuera yo quien tuviese que elegir me quedaría con esta primera variante de código para leer un archivo XML.
    Esta primera variante usa el método Descendants que existe en ambas clases (XElement y XDocument):
    // Código para leer un fichero XML usando LINQ 2 XML
    private static void Linq2XmlLeerFicheroXmlConXElement()
    {
      XElement xmlContactos = XElement.Load("Contactos.xml");
     
      //Obtener el Nombre de todos los contactos
      var contactosAll =
        from c in xmlContactos.Descendants("Contacto")
        select c.Element("Nombre").Value;
     
      //Obtener todos los contactos cuyo nombre comiencen con L
      var contactosL =
        from c in xmlContactos.Descendants("Contacto")
        where c.Element("Nombre").Value.StartsWith("L")
        select c;
     
      //Obtener todos los contactos que al menos uno de los Telefonos sea de Tipo Personal
      var contactosTelPers =
        from c in xmlContactos.Descendants("Contacto")
        where null != c.Elements("Telefono").Attributes("Tipo").
                      FirstOrDefault(t => t.Value == "Personal")
        select c;
    }
    

    Otra variante de código para obtener el mismo resultado:
    // Código para leer un fichero XML usando LINQ 2 XML
    private static void Linq2XmlLeerFicheroXml()
    {
      XDocument docContactos = XDocument.Load("Contactos.xml");
     
      //Obtener el Nombre de todos los contactos
      var contactosAll =
        from c in docContactos.Elements("Contactos").Elements("Contacto")
        select c.Element("Nombre").Value;
     
      //Obtener todos los contactos cuyo nombre comiencen con L
      var contactosL =
        from c in docContactos.Elements("Contactos").Elements("Contacto")
        where c.Element("Nombre").Value.StartsWith("L")
        select c;
     
      //Obtener todos los contactos que al menos uno de los Telefonos sea de Tipo Personal
      var contactosTelPers =
        from c in docContactos.Elements("Contactos").Elements("Contacto")
        where null != c.Elements("Telefono").Attributes("Tipo").
                      FirstOrDefault(t => t.Value == "Personal")
        select c;
    }
    

    Adicionar un elemento a nodos existentes con LINQ to XML

    Existen varias formas en .NET C# para crear un nuevo elemento en un árbol XML, acá expondremos 2 formas distintas:
    XElement.Add: Se describe por si solo, adiciona un nuevo elemento.
    XElement.SetElementValue: Modifica, agrega o elimina un elemento.
    Como vemos en el contenido del archivo XML de arriba, nuestro segundo contacto (Luis) tiene un elemento EMail asociado, imaginemos que queremos modificar el Email. Veamos las 2 variantes de código para obtener dicho resultado:

    // Método XElement.Add
    // Código para adicionar un elemento usando Add (LINQ 2 XML)
    
    private static void Linq2XmlAddEmailUsandoAdd()
    {
      XElement xmlContactos = XElement.Load("Contactos.xml");
     
      //Obtener el contacto con nombre Luis
      var contactoLuis =
         (from c in xmlContactos.Descendants("Contacto")
          where c.Element("Nombre").Value.ToUpper() == "LUIS"
          select c).FirstOrDefault();
     
      if (contactoLuis != null)
      {
        string strXml = @"luis1@gmail.com";
        contactoLuis.Add(XElement.Parse(strXml));
      }
    }
    

    Modificar un elemento de nodos existentes con LINQ to XML

    Si usamos el código que hemos expuesto, en realidad no estamos modificando el Email, sino que estamos adicionando un nuevo Email, es decir para Luis tendríamos ahora 2 Mail, el que tenia anteriormente (luis@gmail.com) y el que recién acabamos de adicionar (luis1@gmail.com). Es decir que no logramos el resultado esperado.
    Para lograrlo teníamos que haber eliminado el nodo y crearlo nuevamente con el valor correcto. Veamos ahora el código usando el segundo método:

    // Método XElement.SetElementValue
    // Código para adicionar un elemento usando SetElementValue (LINQ 2 XML)
    
    private static void Linq2XmlAddEmailUsandoSetElementValue()
    {
      XElement xmlContactos = XElement.Load("Contactos.xml");
     
      //Obtener el contacto con nombre Luis
      var contactoLuis =
         (from c in xmlContactos.Descendants("Contacto")
          where c.Element("Nombre").Value.ToUpper() == "LUIS"
          select c).FirstOrDefault();
     
      if (contactoLuis != null)
        contactoLuis.SetElementValue("EMail", luis2@gmail.com);
    }
    

    Usando este segundo código, sí logramos el resultado esperado, porque el método SetElementValue lo que hace es buscar dentro del elemento contactoLuis, el nodo o elemento EMail y si existe modifica su valor, en caso contrario lo adiciona. si por el contrario quisiéramos modificar todos los atributos de todos los nodos

    XDocument xmlFile = XDocument.Load("Contactos.xml"); 
    var query = from c in xmlFile.Elements("Contactos").Elements("contacto")    
                select c; 
    foreach (XElement contacto in query) 
    {
        contacto.Attribute("attr1").Value = "MyNewValue";
    }
    xmlFile.Save("Contactos.xml");
    

    Si nuestro objetivo hubiese sido eliminar el nodo Email, podríamos haber usado el método SetElementValue con el segundo parámetro en null:
    contactoLuis.SetElementValue("EMail", null);
    

    XElement.SetAttributeValue

    Al igual que el método SetElementValue, existe un método SetAttributeValue que establece, agrega o elimina un atributo de un elemento. Pero veamos un ejemplo donde le cambiemos el atributo del teléfono que tiene Luis (cambiarlo de Móvil a Trabajo):

    // Código para modificar atributo usando SetAttributeValue (LINQ 2 XML)
    private static void Linq2XmlSetAttributeValue()
    {
      XElement xmlContactos = XElement.Load("Contactos.xml");
     
      //Obtener el contacto con nombre Luis
      var contactoLuis =
         (from c in xmlContactos.Descendants("Contacto")
          where c.Element("Nombre").Value.ToUpper() == "LUIS"
             && c.Element("Telefono").HasAttributes
          select c).FirstOrDefault();
     
      if (contactoLuis != null)
        contactoLuis.Element("Telefono").SetAttributeValue("Tipo", "Trabajo");
    }
    

    Nota: En el código anterior, en la consulta hemos preguntado por la propiedad HasAttributes, en realidad carece de sentido en nuestro ejemplo preguntar por dicha propiedad, porque si el elemento Telefono no tuviese atributos igual crearía el atributo Tipo. De todas formas me pareció interesante incorporar la propiedad para que el lector sepa de su existencia, en ocasiones suele ser de utilidad.

    De similar manera que sucede con el SetElementValue, si quisiéramos eliminar un atributo usaríamos el método SetAttributeValue con el segundo parámetro nulo (null).

    Seleccionar Información de Nodo Completo

    private void buscarEnXML(string idCon)
    {
     XDocument miXML = XDocument.Load(@"C:\Prueba\MiDoc.xml");
     
     var nombreusu = from nombre in miXML.Elements("Contactos").Elements("Contacto")
       where nombre.Attribute("Id_Empleado").Value == idCon //Consultamos por el atributo
       select nombre.Element("Nombre").Value; //Seleccionamos el nombre
     
     foreach (string minom in nombreusu)
     {
       MessageBox.Show(minom); //Mostramos un mensaje con el nombre del empleado 
     }
    }
    

    Agregar Nuevo Nodo a documento XML

    Para agregar un nuevo nodo se usa la propiedad Root del XDocument, ésta propiedad obtiene la raiz del documento, dándonos la posibilidad de agregar los elementos y atributos de manera muy fácil, para esto, he creado un método addNode, que espera los parámetros id_Empleado, nombre y edad; todos del tipo string, el código queda así:
    private void addNode(string idEmpleado, string nombre, string edad)
    {
     XDocument miXML = XDocument.Load(@"C:\Prueba\MiDoc.xml"); //Cargamos
     miXML.Root.Add(   //Obtiene la raiz del documento (Empleados)                         
      new XElement("Empleado",
      new XAttribute("Id_Empleado", idEmpleado),
      new XElement("Nombre", nombre),
      new XElement("Edad", edad))
                   );
     miXML.Save(@"C:\Prueba\MiDoc.xml");
    }
    

    Eliminar Nodo de documento XML

    Para eliminar un nodo se debe consultar si este existe, luego si se dispone a eliminar elemento a elemento con un foreach, esta es la forma en que yo lo hago, no se si exista una mas optima, (si conoces alguna te agradecería me lo hicieras saber). Creé un método dropNode, que espera el parámetro IdEmpleado del tipo string, el método queda así:
    private void dropNode(string idEmpleado)
    {
     XDocument miXML = XDocument.Load(@"C:\Prueba\MiDoc.xml"); //Cargar el archivo           
     
     var consul = from persona in miXML.Elements("Empleados").Elements("Empleado")
                  where persona.Attribute("Id_Empleado").Value == idEmpleado
                  select persona;
     consul.ToList().ForEach(x => x.Remove()); //Remover elemento a elemento.
     miXML.Save(@"C:\Prueba\MiDoc.xml");            
    }
    

    9 de mayo de 2015

    Crear XML con C#

    protected void CrearDocumentoXML()
     {
      XDocument miXML = new XDocument(
       new XDeclaration("1.0", "utf-8", "yes"),
       new XComment("Lista de Alumnos"),
       
       new XElement("Alumnos",
       
            new XElement("Alumno",
             new XAttribute("NoControl", "05231104"),
              new XElement("Nombre", "Edison García"),
              new XElement("Semestre", "7")),
    
            new XElement("Alumno",
             new XAttribute("NoControl", "05231106"),
              new XElement("Nombre", "Abraham Gomez García"),
              new XElement("Semestre", "9")),
    
            new XElement("Alumno",
             new XAttribute("NoControl", "05231108"),
              new XElement("Nombre", "Alejandre Carvajal"),
              new XElement("Semestre", "7")),
    
           new XElement("Alumno",
            new XAttribute("NoControl", "06231110"),
             new XElement("Nombre", "Luis Armando"),
              new XElement("Semestre", "10"))                  
        )
      );
    miXML.Save(@"c:\miXML.xml");  } 
    
    Para obtener la ruta del servidor usamos: AppDomain.CurrentDomain.BaseDirectory con lo que quedaría así:
    miXML.Save(AppDomain.CurrentDomain + "miXML.xml";  
    
    Una segunda manera de crear ficheros xml desde C# es :
    private static void Linq2XmlCrearFicheroXml2()
    {
     string strXml = @"
      Juan
      juan@gmail.com
      666666666
      911111111
      ";
     
     XElement xml = XElement.Parse(strXml);
       
     XDocument pruebaXml = new XDocument(xml);
     pruebaXml.Save("Prueba.xml");
    }
    

    8 de mayo de 2015

    Buscador XML con C#

    se va buscar informacion especifica en un archivo xml y se va mostrar esa información especifica en un listView, muestro el archivo prueba.xml
    
    
      
        Pablo el primero
        Programador Cliente-Servidor
      
      
        Pablo el segundo
        Programador Web
      
      
    
    Búsqueda XML según atributo se utilizara Linq to XML para realizar la búsqueda según valor del atributo XML
     string path = "prueba.xml";
                listView1.Items.Clear();
    
                XElement doc = XElement.Load(path);
    
                // var result = from persona in doc.Descendants("persona")
                var result = from persona in doc.Elements("persona")
                             where persona.Attribute("id").Value == "001"
                             select new
                             {
                                 id = Convert.ToString(persona.Attribute("id").Value).Trim(),
                                 nombre = Convert.ToString(persona.Element("nombre").Value).Trim(),
                                 ocupacion = Convert.ToString(persona.Element("ocupacion").Value).Trim()
                             };
    
                foreach (var persona in result)
                {
                    ListViewItem nombre = new ListViewItem("  " + persona.nombre + "  ");
                    ListViewItem ocupacion = new ListViewItem("  " + persona.ocupacion + "  ");
                    listView1.Items.Add("");
                    listView1.Items.Add(nombre);
                    listView1.Items.Add(ocupacion);
                    listView1.Items.Add("");
                    listView1.Items.Add("");
                }
    
    Búsqueda XML segun valor se utilizara Linq to XML para realizar la búsqueda según valor del nodo XML
          string path = "prueba.xml";
    
                listView1.Items.Clear();
    
                XElement doc = XElement.Load(path);
    
                // var result = from persona in doc.Descendants("persona")
                var result = from persona in doc.Elements("persona")
                             where persona.Element("nombre").Value == "Pablo el primero"
                             select new
                             {
                                 id = Convert.ToString(persona.Attribute("id").Value).Trim(),
                                 nombre = Convert.ToString(persona.Element("nombre").Value).Trim(),
                                 ocupacion = Convert.ToString(persona.Element("ocupacion").Value).Trim()
                             };
    
                foreach (var persona in result)
                {
                    ListViewItem nombre = new ListViewItem("  " + persona.nombre + "  ");
                    ListViewItem ocupacion = new ListViewItem("  " + persona.ocupacion + "  ");
                    listView1.Items.Add("");
                    listView1.Items.Add(nombre);
                    listView1.Items.Add(ocupacion);
                    listView1.Items.Add("");
                    listView1.Items.Add("");
                }
    

    Abrir XML con C# ListView

    Se mostrara el contenido del archivo xml en un listView utilizando C#, el contenido del archivo xml es
    
    
      
        Pablo el primero
        Programador Cliente-Servidor
      
      
        Pablo el segundo
        Programador Web
      
      
    
    en el evento Load() del formulario colocar este codigo
     listView1.View = View.Details;
     listView1.Clear();
     listView1.Columns.Clear();
     listView1.Columns.Add("", 400);
    
    Utilizando XMLTextReader El primer ejemplo utiliza XMLTextReader para mostrar el formato del archivo xml, es decir, ademas de mostrar la información, se mostrara ordenada y con sus nodos tal cual esta codificado
    private void buttonXML_Click(object sender, EventArgs e){
         
    XmlTextReader reader = new XmlTextReader("prueba.xml");
     while (reader.Read())
     {
     switch (reader.NodeType)
      {
       case XmlNodeType.Element: // The node is an element.
       listView1.Items.Add("<" + reader.Name + ">");
       break;
       case XmlNodeType.Text: //Display the text in each element.
       listView1.Items.Add(reader.Value);
       break;
       case XmlNodeType.EndElement: //Display the end of the element.
       listView1.Items.Add("");
       break;
      }
     }
    }
    
    XMLDocument y XMLNodeList Para visualizar el contenido del archivo xml mostrado anteriormente en un listBox utilizando XMLDocument y XMLNodeList se tiene este codigo
    private void BXML_Click(object sender, EventArgs e)
     {
      listView1.Clear();
      listView1.Columns.Clear();
      listView1.Columns.Add("prueba.xml", 400);
    
     XmlDocument xml = new XmlDocument();
     xml.Load("prueba.xml"); 
    
     XmlNodeList xnList = xml.SelectNodes("/personas/persona");
      foreach (XmlNode xn in xnList)
       {
        string nombre = xn["nombre"].InnerText;
        string ocupacion = xn["ocupacion"].InnerText;
        listView1.Items.Add(nombre);
        listView1.Items.Add(ocupacion);
       }
     }
    
    pero si el archivo xml tiene la forma
    
    
      
      
     
    
    este código te servirá
    private void button1_Click(object sender, EventArgs e){
       listView1.Clear();
       listView1.Columns.Clear();
       listView1.Columns.Add("Nombre", 100, HorizontalAlignment.Left);
       
     XmlDocument xDoc = new XmlDocument();
      try
       {
        xDoc.Load("prueba2.xml");
        XmlNodeList personas = xDoc.GetElementsByTagName("personas");
        XmlNodeList lista = ((XmlElement)personas[0]).GetElementsByTagName("persona");
        int i = 0;
    
        foreach (XmlElement nodo in lista)
         {
          string nNombre = nodo.GetAttribute("id");
          listView1.Items.Add(nNombre);
          string nApellido1 = nodo.GetAttribute("nombre");
          listView1.Items.Add(nApellido1);
    
          string nApellido2 = nodo.GetAttribute("ocupacion");
          listView1.Items.Add(nApellido2);
    
          listView1.Items.Add("");
    
        i++;
         }
       }
       catch (Exception ex) { throw new ArgumentException(ex.Message); }
     }
    
    XDocument - XAttribute - XElement esta solución fue una respuesta de un hilo de stackoverflow creado por mi, funciono bastante bien y no importa cual sea el documento xml, siempre va mostrar los nodos con sus respectivos nombres y los valores de estos
    private void button1_Click(object sender, EventArgs e)
     {
      string xml =
    @"
    
     
      Pablo el primero
      Programador Cliente-Servidor
     
     
      Pablo el segundo
      Programador Web
     
    ";
    
     XDocument doc = XDocument.Parse(xml);
     List ItemList = new List();
      foreach (XElement elem in doc.Elements())
       {
       AddNewItemToList(ItemList, elem);
       }
       listView1.Items.AddRange(ItemList.ToArray());
       }
    
    private void AddNewItemToList(List ItemList, XElement elem)
     {
      string attributes = "";
      if (elem.HasAttributes)
       {
        foreach (XAttribute attr in elem.Attributes())
         {
          attributes += " " + attr.Name + "=\"" + attr.Value + "\"";
         }
        }
    
      if (elem.HasElements)
      {
       ItemList.Add(new ListViewItem("<" + elem.Name + attributes + ">"));
       foreach (XElement childElem in elem.Elements())
       {
        AddNewItemToList(ItemList, childElem);
       }
        ItemList.Add(new ListViewItem(""));
       }
       else
       {
        ItemList.Add(new ListViewItem("<" + elem.Name + attributes + ">" + elem.Value + ""));
       }
    }
    
    Linq to XML el segundo ejemplo utiliza Linq to XML para recuperar la información del xml pero no muestra el formato, es decir, no aparecerán los nodos, ante tal situación agregare items al listView a fin de representar los nodos del archivo pero...pero...esta solución funcionara solo para el archivo xml mostrado al principio de la entrada, por ejemplo si tienes otro xml con nombre de nodos diferentes pues ya no te funcionara, por ejemplo el código anterior no funcionaria con este xml
    
    
     
     God of War III 
     60 
    
    
    ...
    
    
    ...
    
    
    
    este es el código, para este ejemplo no utilizare una clase que represente los nodos del archivo xml
    private void buttonXML_Click(object sender, EventArgs e)
     {
      string path = "prueba.xml";
      listView1.Items.Clear();
           
      XElement doc = XElement.Load(path);
      // var result = from persona in doc.Descendants("persona")
      var result = from persona in doc.Elements("persona")
          select new
             {
              id = Convert.ToString(persona.Attribute("id").Value).Trim(),
              nombre = Convert.ToString(persona.Element("nombre").Value).Trim(),
              ocupacion = Convert.ToString(persona.Element("ocupacion").Value).Trim()
             };  
    
               foreach (var persona in result)
                {
                 ListViewItem nombre = new ListViewItem("  " + persona.nombre + "  ");
                 ListViewItem ocupacion = new ListViewItem("  " + persona.ocupacion + "  ");
                 listView1.Items.Add("");
                 listView1.Items.Add(nombre);
                 listView1.Items.Add(ocupacion);
                 listView1.Items.Add("");
                 listView1.Items.Add("");
               }
     }
    
    pero que pasa si el archivo xml tiene esta forma
    
    
      
      
     
    
    entonces utilizamos la misma lógica para el código pero obtenemos el valor con Attribute
    private void button2_Click(object sender, EventArgs e)
     {
       string path = "prueba2.xml";
       listView1.Items.Clear();
    
       XElement doc = XElement.Load(path);
       // var result = from persona in doc.Descendants("persona")
       var result = from persona in doc.Elements("persona")
          select new
           {
            id = Convert.ToString(persona.Attribute("id").Value).Trim(),
            nombre = Convert.ToString(persona.Attribute("nombre").Value).Trim(),
            ocupacion = Convert.ToString(persona.Attribute("ocupacion").Value).Trim()
            };
    
             foreach (var persona in result)
              {
               listView1.Items.Add("");
               listView1.Items.Add("");
              }
            }
    
    Linq to XML Por ultimo se mostrara como utilizar una clase que represente el archivo xml que se desea mostrar, esta solución es la correcta por ser orientada a objetos pero como viste anteriormente no es la única e igualmente las soluciones anteriores funcionan en su cometido. De nuevo utilizamos el archivo xml mostrado al inicio de la entrada, para este ejemplo se crea una nueva clase de nombre persona.cs la cual contendra un metodo que recuperara toda la informacion del archivo xml en una lista de entidades, la clase quedaría de la siguiente manera
    using System.Xml.Linq;
    
    namespace pabletoreto.blogspot.com
    {
     class persona
      {
       private int idPersona;
       private string nombrePersona;
       private string ocupacionPersona;
    
       public int _idPersona
        {
         get { return idPersona; }
         set { idPersona = value; }
        }
       public string _nombrePersona
        {
         get { return nombrePersona; }
         set { nombrePersona = value; }
        }
       public string _ocupacionPersona
        {
         get { return ocupacionPersona; }
         set { ocupacionPersona = value; }
        }
    
       public persona() { }
       public persona(int id, string nombre, string ocupacion) {
        this._idPersona = id;
        this._nombrePersona = nombre;
        this._ocupacionPersona = ocupacion;
       }
    
       public List leerXML( string path){
        var consulta =
          from valor in XElement.Load(path).Elements("persona")
          select new persona{
            _idPersona = Convert.ToInt32(Convert.ToString( valor.Attribute("id").Value ).Trim( ) ),
            _nombrePersona = Convert.ToString( valor.Element( "nombre" ).Value ).Trim( ),
            _ocupacionPersona = Convert.ToString(valor.Element( "ocupacion" ).Value ).Trim( )
          };
        List personas = consulta.ToList();
        return personas;
        }
      }
    }
    
    y desde el evento click de un botón colocamos este código
    private void button5_Click(object sender, EventArgs e)
     {
      string path ="prueba.xml";
      persona ps = new persona();
       foreach( persona valor in ps.leerXML(path) ){
        ListViewItem nombre = new ListViewItem("  " + valor._nombrePersona + "  ");
        ListViewItem ocupacion = new ListViewItem("  " + valor._ocupacionPersona + "  ");
        listView1.Items.Add("");
        listView1.Items.Add(nombre);
        listView1.Items.Add(ocupacion);
        listView1.Items.Add("");
        listView1.Items.Add("");
       }
     }