none
Procesar XML RRS feed

  • Pregunta

  • Buen día.

    Estoy tratando de procesar un archivo XML con XMLDocument, pero mi problema viene al intentar leer los nodos anidados ya que la estructura es algo compleja para alguien que nunca había manejado este tipo de archivos.

    Tengo algo parecido a lo siguiente:

    <Cliente>

         <LIN>

              <LIN.LIN>

                   <LIN03> Articulo

              </LIN.LIN>

              <LIN.FST>

                   <LIN.FST.FST>

                        <FST01> Cantidad Total

                   <LIN.FST.FST>

                   <LIN.FST.JIT>

                        <LIN.FST.JIT.JIT>

                             <JIT01> Cantidad desglose

                        </LIN.FST.JIT.JIT>

                   </LIN.FST.JIT>

              </LIN.FST>

         </LIN>

    </Cliente>

    Dentro del archivo hay varios nodos LIN que es donde viene el requerimiento, pero no sé como hacer que entre a los nodos hijos de cada uno, ya que al recorrerlo me da todos los nodos LIN con sus hijos.

    Agradecería mucho su ayuda

    lunes, 6 de julio de 2015 16:39

Respuestas

  • hola

    podrias implementar una lectura recursiva por lo nodo, digo si la idea es ir recorriendolos todos

    Recursively processing XML elements in C#

    por supuesto tienes que adaptarlo a tu caso, pero la idea es analizando en la profundidad de nodos

    o buscas obtener los datos de algunso en particular?

    saludo


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    martes, 7 de julio de 2015 5:37
  • Si estás usando un XmlDocument, me imagino que estarás empleando una llamada a SelectNodes para obtener todos los nodos con una expresión XPATH tal como documento.SelectNodes("//LIN").

    Pues bien, si recorres con un bucle el XmlNodeList que te devuelve, por cada nodo puedes volver a lanzar un SelectNodes que te busque lo que quieras en los nodos hijos, p.ej:

    var hijos = nodo.SelectNodes("/LIN.LIN")

    De esta manera, y si sabes lo que buscar dentro del XML, puedes ir recorriendo a tu gusto el árbol XML tal como lo requiera la lógica de tu programa.

    martes, 7 de julio de 2015 7:23

Todas las respuestas

  • hola

    podrias implementar una lectura recursiva por lo nodo, digo si la idea es ir recorriendolos todos

    Recursively processing XML elements in C#

    por supuesto tienes que adaptarlo a tu caso, pero la idea es analizando en la profundidad de nodos

    o buscas obtener los datos de algunso en particular?

    saludo


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    martes, 7 de julio de 2015 5:37
  • Si estás usando un XmlDocument, me imagino que estarás empleando una llamada a SelectNodes para obtener todos los nodos con una expresión XPATH tal como documento.SelectNodes("//LIN").

    Pues bien, si recorres con un bucle el XmlNodeList que te devuelve, por cada nodo puedes volver a lanzar un SelectNodes que te busque lo que quieras en los nodos hijos, p.ej:

    var hijos = nodo.SelectNodes("/LIN.LIN")

    De esta manera, y si sabes lo que buscar dentro del XML, puedes ir recorriendo a tu gusto el árbol XML tal como lo requiera la lógica de tu programa.

    martes, 7 de julio de 2015 7:23
  • A ver si esto te puede ayudar, que es bastante simple y se recorre bastante rápido. Tal vez no es lo más dinámico, o correcto, pero funciona.

    Yo tengo para una estructura de este tipo :

    <root>

    <CLIENTES>

    <Cliente>

    <Codigo>

    <Nombre>

    </Cliente>

    <Cliente>

    <Codigo>

    <Nombre>

    </Cliente>

    </CLIENTES>

    <DIRECCIONES>

    <Direccion>

    <Codigo>

    </Direccion>

    <DIRECCIONES>

    </root>

     El código para recorrerlo es el siguiente:
              if (documentoXML != null){XmlNodeList xmlObject = documentoXML.GetElementsByTagName("root");
    
    if (xmlObject != null){
    
    if (xmlObject.Item(0).HasChildNodes()){
    
    foreach (XmlElement xmlTabla in xmlObject.Item(0).ChildNodes){objXMLTabla = xmlTabla.ChildNodes;if (objXMLTabla != null){ 
    
    if (xmlTabla.GetAttribute("Nombre") == "CLIENTES")
    {
    foreach (XmlElement xmlCliente in xmlTabla.ChildNodes)
    {
    if (xmlCliente.NodeName == "Cliente"){
    
    Cliente clie = new Cliente();     
     
    if (xmlCliente.GetElementsByTagName("Codigo").Item(0) != null){ 
    clie.Codigo = Convert.ToString(xmlCliente.GetElementsByTagName("Codigo").Item(0).InnerText); 
    }
    if (xmlCliente.GetElementsByTagName("Nombre").Item(0) != null){ clie.Nombre = Convert.ToString(xmlCliente.GetElementsByTagName("Nom").Item(0).InnerText); }
    
    }
    }
    else if (xmlTabla.GetAttribute("Nombre") == "DIRECCIONES")
    {...}
    

    Espero te ayude!

    • Propuesto como respuesta ibis48 martes, 7 de julio de 2015 8:05
    martes, 7 de julio de 2015 8:05
  • Muchas gracias Leandro, voy a intentar con este método y validando cada nodo, ya que como comentas necesito obtener solo ciertos registros para volcar los datos en una tabla y posteriormente hacerla una tabla pivote.

    Saludos!

    miércoles, 8 de julio de 2015 20:48
  • Muchas gracias Alberto, voy a intentar realizar pruebas como comentas, lo había intentado sin el segundo SelectNodes y me devolvía todos los nodos hijos de los todos los nodos <LIN>

    Saludos!

    miércoles, 8 de julio de 2015 21:03
  • Buenas, amigo en mi caso la estructura es algo diferente y no he encontrado ejemplos o alguién que me oriente de forma directa acerca de este caso... tengo un archivo .xml pero son sus propiedades la que contiene su valor. Por ejemplo.

    <Export>
    
     <Invoices>
    
     <Invoice Serie="T" Number="19" BusinessDay="2016-03-09" VatIncluded="true" PrintCount="1" Date="2016-03-11T14:22:31">
    
    <Pos Id="1" Name="TPV" />
    
    <User Id="1" Name="admin" />
    
    </Invoices>
    
    </Export>




    he intentado con este recorrido que funciona para archivos del caso del señor de este tema... fijate.


    XDocument documento = XDocument.Load(@"C:\Users\desarrollo\Documents\AE AGORA\Invoice-T-000019.xml");
    
                var Invoices = from usu in documento.Descendants("Invoices") select usu;
    
                foreach(XElement u in Invoices.Elements("Invoice"))
                {
                    Console.WriteLine(u.Element("Pos").Value);
                    Console.WriteLine(u.Element("User").Value);
    
                }
                Console.ReadLine();

    Obviamente está incompleto, pero no me trae nada y cuando aplico esta misma lógica de recorrido a archivos de tipo como el expuesto aquí si funciona y trae los datos limpios como por ejemplo este.

    <ARCHIVOS>
    <USUARIOS>
    <USUARIO>Carlos</USUARIO>
    <EDAD>19</EDAD>
    <PROFESION>INGENIERO</PROFESION>
    </USUARIOS>
    </ARCHIVOS>

    ¿Pero como se haría en el caso que yo pregunto?, ¿cómo dentro de esos nodos obtengo el valor de sus propiedades o elementos que lo componen?, espero haber formulado bien la pregunta.




    viernes, 11 de marzo de 2016 19:22
  • Eres un genio, amigo, gracias por tu código, viendolo me dió una idea para capturar los atributos al ver está condición...

    if (xmlTabla.GetAttribute("Nombre") == "CLIENTES")

    pude verificar y jurungar en las propiedades y ver un Atributo y adaptar mi código de esta manera.

                var Invoices = from usu2 in documento.Descendants("Invoices") select usu2;
    
                foreach (XElement e in Invoices.Elements("Invoice"))
                {
                    Console.WriteLine(e.Element("Pos").Attribute("Id"));
                    Console.WriteLine(e.Element("User").LastAttribute);
                }

    de esa manera ahora si trabajo los atributos de las etiquetas y puedo traerme lo que tenga... el unico inconvenientes es que si tengo esto.

    <Pos Id="1" Name="TPV" />

    me va a traer es Id ="1" Name="TPV" y no solamente 1 y TPV...pero no importa con unas funciones de cadena y ciclos para recorrer arreglos soluciono eso para sacar de la cadena por ejemplo, teniendo algo así... Name="TPV", sacar solo el TPV.

    Es para un proyecto de facturación en impresoras fiscales, donde tengo que obtener toda la información de un xml que genera un programa en caja despues de facturar y yo traducirlo pasarlo a texto plano y mandarlo por la impresora. Saludos y éxitos.

    viernes, 11 de marzo de 2016 22:03