none
Buscar registros dentro de un xml RRS feed

  • Pregunta

  • Estoy realizando una aplicación para un pda, programando en c# con visual studio 2005.
    Utilizo archivos xml en vez de una base de datos , son archivos xml que consigo sincronizando la misma aplicación con otra aplicación similar que tengo en el pc.
    Mi problema es el siguiente:
    Tengo el siguiente archivo xml por ejemplo--->


    <?xml version="1.0" standalone="yes"?>
    <clientesDataSet xmlns="http://tempuri.org/clientesDataSet.xsd">
      <cliente>
        <cod_cliente>c005</cod_cliente>
        <dni>34598098</dni>
        <nombre>isabel</nombre>
        <apellidos>borrero</apellidos>
        <direccion>avda castrelos</direccion>
        <cod_comercial>co03</cod_comercial>
      </cliente>
      <cliente>
        <cod_cliente>c01</cod_cliente>
        <dni>34596870</dni>
        <nombre>alberto</nombre>
        <apellidos>gomez</apellidos>
        <direccion>avda portanet</direccion>
        <cod_comercial>c01</cod_comercial>
      </cliente>
      </clientesDataSet>

    Mi problema es el siguiente...

    Necesito por ejemplo borrar un cliente, el que esté señalado en el datagrid, donde se visualizan los clientes:

    He hecho los siguiente:

    private void btneliminar_Click(object sender, EventArgs e)
            {
                XmlDocument xmldoc = new XmlDocument();
                xmldoc.Load("cliente.txt");
                /
              
                for (int i = 0; i <= dsclientes.Tables[0].Rows.Count - 1; i++)
                {
                    if (dataGridclientes.IsSelected(i))
                    {
                        string filaaborrar = dsclientes.Tables[0].RowsIdea.ItemArray[0].ToString();
                        XmlNodeList nodeList;
                        XmlNode root = xmldoc.DocumentElement;

                        nodeList = root.SelectNodes("/clientesDataSet/cliente[@cod_cliente=filaaborrar.Value]");
                      


                       
                       
                       
                        mlNode nodoborrar = root.SelectSingleNode("/clientesDataSet/cliente[@cod_cliente=filaaborrar.Value]");
                       

                        hijo.RemoveAll();
                        dsclientes.Tables[0].RowsIdea.Delete(); //lo eliminamos del datagrid
                       


                       
                    }
                }


            }

    Consigo eliminarlo del datagrid, pero no eliminarlo del Xml.....
    Alguien me puede ayudar???

           

           

           

          
     



    lunes, 15 de octubre de 2007 15:18

Respuestas

  • Para el error: Un pequeño fallo, en el SelectSingleNode hay que pasar el NameSpaceManager:

     

    XmlNode nodoborrar = doc.SelectSingleNode("//x:clientesDataSet/x:cliente[x:cod_cliente='" + filaaborrar + "']", nsManager);

     

    Lo de la "x": Es un identificador arbitrario que sirve para designar el espacio de nombres. Se puede usar cualquier otro nombre si la x no te gusta, es solo una variable para indicar en cada elemento del Xml el espacio de nombres al que pertenece. Esto se debe a que en tu Xml original se establece al principio un espacio de nombres predeterminado para todos los elementos (lo del xmlns=...). Aunque el archivo en sí entiende que todos los elementos pertenecen de forma predeterminada a ese espacio de nombres, las consultas XPath que se usan en el XmlDocument no lo entienden, y es necesario ponerles a todos los elementos el espacio de nombres.

     

    Por cierto, ahora mismo no estoy seguro, pero creo que lo de nodoborrar.RemoveAll() que has puesto solo borra lo que cuelga del nodo, pero no el nodo en sí mismo. Si es asi, tendrás que subir un nivel al nodo padre para borrar desde él el nodo que quieres quitar.

     

    martes, 16 de octubre de 2007 9:20
    Moderador

Todas las respuestas

  • Veo varios fallos: Uno es que el XML tiene un espacio de nombres predeterminado, y no lo has añadido en el código que realiza la búsqueda. Otro es que el cod_cliente lo estás intentando buscar como si fuera un atributo, cuando en realidad es un elemento. El último es mucho más tonto y me imagino que ya te habrás dado cuenta: has dejado el filaaborrar.Value dentro de las comillas del XPath.

     

    Bloque de código

    const string miEspacio = "http://tempuri.org/clientesDataSet.xsd";

    XmlDocument doc = new XmlDocument();

    doc.Load("cliente.txt");

    XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable);

    nsManager.AddNamespace("x", miEspacio);

    ...

    mlNode nodoborrar = doc.SelectSingleNode("//x:clientesDataSet/x:cliente[x:cod_cliente='"+filaaborrar.Value+"']");

    ...

     

     

     

    martes, 16 de octubre de 2007 7:43
    Moderador

  • He puesto lo siguiente en mi aplicación:

    using System.Xml.XPath;
    using System.Xml.Xslt;

    private void btneliminar_Click(object sender, EventArgs e)
            {
                const string miEspacio = "http://tempuri.org/clientesDataSet.xsd";
                XmlDocument doc = new XmlDocument();
                doc.Load("cliente.txt");
                XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable);
                nsManager.AddNamespace("x", miEspacio);
               
                for (int i = 0; i <= dsclientes.Tables[0].Rows.Count - 1; i++)
                {
                    if (dataGridclientes.IsSelected(i))
                    {
                        string filaaborrar = dsclientes.Tables[0].RowsIdea.ItemArray[0].ToString();
                      
                        XmlNode nodoborrar = doc.SelectSingleNode("//x:clientesDataSet/x:cliente[x:cod_cliente='" + filaaborrar + "']");
                        nodoborrar.RemoveAll();
                        dsclientes.Tables[0].RowsIdea.Delete(); //lo eliminamos del datagrid
                       


                       
                    }
                }

               
            }

    Y al ejecutarlo me da la siguiente excepción:
    Es necesario el administración de espacios de nombres o XSLContext.Esta consulta tiene un prefijo, una variable o una función definida por el usuario.
    Y no la doy resuelto

    Y otra cosa no entiendo pq en nSManager.AddNamesapce le añades una x ,  si me lo pudieses explicar.
    Gracias por la ayuda Wink
    martes, 16 de octubre de 2007 8:47
  • Para el error: Un pequeño fallo, en el SelectSingleNode hay que pasar el NameSpaceManager:

     

    XmlNode nodoborrar = doc.SelectSingleNode("//x:clientesDataSet/x:cliente[x:cod_cliente='" + filaaborrar + "']", nsManager);

     

    Lo de la "x": Es un identificador arbitrario que sirve para designar el espacio de nombres. Se puede usar cualquier otro nombre si la x no te gusta, es solo una variable para indicar en cada elemento del Xml el espacio de nombres al que pertenece. Esto se debe a que en tu Xml original se establece al principio un espacio de nombres predeterminado para todos los elementos (lo del xmlns=...). Aunque el archivo en sí entiende que todos los elementos pertenecen de forma predeterminada a ese espacio de nombres, las consultas XPath que se usan en el XmlDocument no lo entienden, y es necesario ponerles a todos los elementos el espacio de nombres.

     

    Por cierto, ahora mismo no estoy seguro, pero creo que lo de nodoborrar.RemoveAll() que has puesto solo borra lo que cuelga del nodo, pero no el nodo en sí mismo. Si es asi, tendrás que subir un nivel al nodo padre para borrar desde él el nodo que quieres quitar.

     

    martes, 16 de octubre de 2007 9:20
    Moderador
  • Bueno he puesto lo siguiente para poder borrar el nodo que quiero y me sigue sin funcionar Sad, se supone que el xml del que quiero borrar es el que pongo al principio, pero no me borra nada , que estoy haciendo mal Sad, si ahora me selecciona el que tiene que seleccionar .

    XmlNode root = doc.DocumentElement;
                        XmlNode nodoborrar = root.SelectSingleNode("//x:clientesDataSet/x:cliente[x:cod_cliente='" + filaaborrar + "']",nsManager);
                       
                        dsclientes.Tables[0].RowsIdea.Delete(); //lo eliminamos del datagrid
                        root.RemoveChild(nodoborrar);


    Muchas gracias por la ayuda que me estas dando Big Smile
    martes, 16 de octubre de 2007 14:22
  • Muchas gracias por la ayuda he encontrado la solucion se me olvidaba poner al final
    doc.Save("cliente.txt")


    Muchas gracias por la ayuda ya voy solucionando poco a poco los problemas....
    martes, 16 de octubre de 2007 15:28
  • Muchas gracias por la ayuda he encontrado la solucion se me olvidaba poner al final
    doc.Save("cliente.txt")


    Muchas gracias por la ayuda ya voy solucionando poco a poco los problemas....
    martes, 16 de octubre de 2007 17:56