Search code examples
c#xmlxml-parsingxml-deserialization

Is there a way to deserialize an XML file even if there are missing nodes or more nodes than there should be? C#


I'm working with a lot of XML files that are similar but sometimes each one has more or less nodes. (Let's say that is a billing from a purchase or something like that). But i need to deserialize the XML even when it doesn't match the structure (I need to get common nodes to my class). Node Names won't differ but there may be more nodes than usual

        String MainXMLPATH = AppPrincipal.PathDeLecturaIndividual; //Gets xml path from another form
        XmlDocument dom = new XmlDocument();
        dom.Load(MainXMLPATH); //Loads xml
            XmlSerializer serializer = new XmlSerializer(typeof(FacturaElectronica)); //Autogenerated Visual Studio class from XML
            FacturaElectronica I;
            using (Stream reader = new FileStream(MainXMLPATH, FileMode.Open)) {
                // Call the Deserialize method to restore the object's state.
                I = (FacturaElectronica)serializer.Deserialize(reader);
            }
        Console.WriteLine(I.Clave + "," + I.CodigoActividad + "," + I.CondicionVenta + "," + I.DetalleServicio + "," + I.Emisor.CorreoElectronico);//Prints the value of my xml

This is my class:

    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "https://cdn.comprobanteselectronicos.go.cr/xml-schemas/v4.3/facturaElectronica")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "https://cdn.comprobanteselectronicos.go.cr/xml-schemas/v4.3/facturaElectronica", IsNullable = false)]
    public partial class FacturaElectronica {

        private string claveField;

        private uint codigoActividadField;

        private ulong numeroConsecutivoField;

        private System.DateTime fechaEmisionField;

        private FacturaElectronicaEmisor emisorField;

        private FacturaElectronicaReceptor receptorField;

        private byte condicionVentaField;

        private byte plazoCreditoField;

        private byte[] medioPagoField;

        private FacturaElectronicaLineaDetalle[] detalleServicioField;

        private FacturaElectronicaOtrosCargos[] otrosCargosField;

        private FacturaElectronicaResumenFactura resumenFacturaField;

        private Signature signatureField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(DataType = "integer")]
        public string Clave {
            get {
                return this.claveField;
            }
            set {
                this.claveField = value;
            }
        }

        /// <remarks/>
        public uint CodigoActividad {
            get {
                return this.codigoActividadField;
            }
            set {
                this.codigoActividadField = value;
            }
        }

        /// <remarks/>
        public ulong NumeroConsecutivo {
            get {
                return this.numeroConsecutivoField;
            }
            set {
                this.numeroConsecutivoField = value;
            }
        }

        /// <remarks/>
        public System.DateTime FechaEmision {
            get {
                return this.fechaEmisionField;
            }
            set {
                this.fechaEmisionField = value;
            }
        }

        /// <remarks/>
        public FacturaElectronicaEmisor Emisor {
            get {
                return this.emisorField;
            }
            set {
                this.emisorField = value;
            }
        }

        /// <remarks/>
        public FacturaElectronicaReceptor Receptor {
            get {
                return this.receptorField;
            }
            set {
                this.receptorField = value;
            }
        }

        /// <remarks/>
        public byte CondicionVenta {
            get {
                return this.condicionVentaField;
            }
            set {
                this.condicionVentaField = value;
            }
        }

        /// <remarks/>
        public byte PlazoCredito {
            get {
                return this.plazoCreditoField;
            }
            set {
                this.plazoCreditoField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute("MedioPago")]
        public byte[] MedioPago {
            get {
                return this.medioPagoField;
            }
            set {
                this.medioPagoField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlArrayItemAttribute("LineaDetalle", IsNullable = false)]
        public FacturaElectronicaLineaDetalle[] DetalleServicio {
            get {
                return this.detalleServicioField;
            }
            set {
                this.detalleServicioField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute("OtrosCargos")]
        public FacturaElectronicaOtrosCargos[] OtrosCargos {
            get {
                return this.otrosCargosField;
            }
            set {
                this.otrosCargosField = value;
            }
        }

        /// <remarks/>
        public FacturaElectronicaResumenFactura ResumenFactura {
            get {
                return this.resumenFacturaField;
            }
            set {
                this.resumenFacturaField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.w3.org/2000/09/xmldsig#")]
        public Signature Signature {
            get {
                return this.signatureField;
            }
            set {
                this.signatureField = value;
            }
        }
    }

Example XML:

<FacturaElectronica xmlns="https://cdn.comprobanteselectronicos.go.cr/xml-schemas/v4.3/facturaElectronica" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <Clave>50601082000310133465800100001010000038444100147136</Clave>
    <CodigoActividad>642005</CodigoActividad>
    <NumeroConsecutivo>00100001010000038444</NumeroConsecutivo>
    <FechaEmision>2020-08-01T19:47:58-06:00</FechaEmision>
    <Emisor>
        <Nombre>Callmyway NY</Nombre>
        <Identificacion>
            <Tipo>02</Tipo>
            <Numero>3101334658</Numero>
        </Identificacion>
        <Ubicacion>
            <Provincia>1</Provincia>
            <Canton>01</Canton>
            <Distrito>05</Distrito>
            <Barrio>13</Barrio>
            <OtrasSenas>COSTADO NORTE COLEGIO ABOGADOS FRENTE ENTRADA PRINCIPAL</OtrasSenas>
        </Ubicacion>
        <Telefono>
            <CodigoPais>506</CodigoPais>
            <NumTelefono>40004000</NumTelefono>
        </Telefono>
        <CorreoElectronico>[email protected]</CorreoElectronico>
    </Emisor>
    <Receptor>
        <Nombre>GRUPO APLIX LATINOAMERICA SOCIEDAD ANONIMA</Nombre>
        <Identificacion>
            <Tipo>02</Tipo>
            <Numero>3101753993</Numero>
        </Identificacion>
    </Receptor>
    <CondicionVenta>01</CondicionVenta>
    <PlazoCredito>0</PlazoCredito>
    <MedioPago>04</MedioPago>
    <MedioPago>02</MedioPago>
    <DetalleServicio>
        <LineaDetalle>
            <NumeroLinea>1</NumeroLinea>
            <CodigoComercial>
                <Tipo>04</Tipo>
                <Codigo>TR</Codigo>
            </CodigoComercial>
            <Cantidad>1</Cantidad>
            <UnidadMedida>St</UnidadMedida>
            <Detalle>Consumo Mensual Celular (2020-07)(6h23m9s)</Detalle>
            <PrecioUnitario>839.99764</PrecioUnitario>
            <MontoTotal>839.99764</MontoTotal>
            <SubTotal>839.99764</SubTotal>
            <BaseImponible>839.99764</BaseImponible>
            <Impuesto>
                <Codigo>01</Codigo>
                <CodigoTarifa>08</CodigoTarifa>
                <Tarifa>13.00</Tarifa>
                <Monto>109.19969</Monto>
            </Impuesto>
            <ImpuestoNeto>109.19969</ImpuestoNeto>
            <MontoTotalLinea>949.19733</MontoTotalLinea>
        </LineaDetalle>
        <LineaDetalle>
            <NumeroLinea>2</NumeroLinea>
            <CodigoComercial>
                <Tipo>04</Tipo>
                <Codigo>TR</Codigo>
            </CodigoComercial>
            <Cantidad>1</Cantidad>
            <UnidadMedida>St</UnidadMedida>
            <Detalle>Consumo Mensual Fijo (2020-07)(1h58m54s)</Detalle>
            <PrecioUnitario>903.64052</PrecioUnitario>
            <MontoTotal>903.64052</MontoTotal>
            <SubTotal>903.64052</SubTotal>
            <BaseImponible>903.64052</BaseImponible>
            <Impuesto>
                <Codigo>01</Codigo>
                <CodigoTarifa>08</CodigoTarifa>
                <Tarifa>13.00</Tarifa>
                <Monto>117.47327</Monto>
            </Impuesto>
            <ImpuestoNeto>117.47327</ImpuestoNeto>
            <MontoTotalLinea>1021.11379</MontoTotalLinea>
        </LineaDetalle>
        <LineaDetalle>
            <NumeroLinea>3</NumeroLinea>
            <CodigoComercial>
                <Tipo>04</Tipo>
                <Codigo>TR</Codigo>
            </CodigoComercial>
            <Cantidad>1</Cantidad>
            <UnidadMedida>St</UnidadMedida>
            <Detalle>Consumo Mensual internacional (2020-07)(2m47s)</Detalle>
            <PrecioUnitario>297.81699</PrecioUnitario>
            <MontoTotal>297.81699</MontoTotal>
            <SubTotal>297.81699</SubTotal>
            <BaseImponible>297.81699</BaseImponible>
            <Impuesto>
                <Codigo>01</Codigo>
                <CodigoTarifa>08</CodigoTarifa>
                <Tarifa>13.00</Tarifa>
                <Monto>38.71621</Monto>
            </Impuesto>
            <ImpuestoNeto>38.71621</ImpuestoNeto>
            <MontoTotalLinea>336.53320</MontoTotalLinea>
        </LineaDetalle>
        <LineaDetalle>
            <NumeroLinea>4</NumeroLinea>
            <CodigoComercial>
                <Tipo>04</Tipo>
                <Codigo>TR</Codigo>
            </CodigoComercial>
            <Cantidad>1</Cantidad>
            <UnidadMedida>St</UnidadMedida>
            <Detalle>Seleccion numero a la carta: 40015220</Detalle>
            <PrecioUnitario>4357.29847</PrecioUnitario>
            <MontoTotal>4357.29847</MontoTotal>
            <SubTotal>4357.29847</SubTotal>
            <BaseImponible>4357.29847</BaseImponible>
            <Impuesto>
                <Codigo>01</Codigo>
                <CodigoTarifa>08</CodigoTarifa>
                <Tarifa>13.00</Tarifa>
                <Monto>566.44880</Monto>
            </Impuesto>
            <ImpuestoNeto>566.44880</ImpuestoNeto>
            <MontoTotalLinea>4923.74727</MontoTotalLinea>
        </LineaDetalle>
    </DetalleServicio>
    <OtrosCargos>
        <TipoDocumento>02</TipoDocumento>
        <Detalle>Timbre de la Cruz Roja</Detalle>
        <MontoCargo>63.98754</MontoCargo>
    </OtrosCargos>
    <OtrosCargos>
        <TipoDocumento>99</TipoDocumento>
        <Detalle>Contribucion 911</Detalle>
        <MontoCargo>47.99065</MontoCargo>
    </OtrosCargos>
    <ResumenFactura>
        <CodigoTipoMoneda>
            <CodigoMoneda>CRC</CodigoMoneda>
            <TipoCambio>1</TipoCambio>
        </CodigoTipoMoneda>
        <TotalServGravados>6398.75362</TotalServGravados>
        <TotalServExentos>0.00000</TotalServExentos>
        <TotalServExonerado>0.00000</TotalServExonerado>
        <TotalMercanciasGravadas>0.00000</TotalMercanciasGravadas>
        <TotalMercanciasExentas>0.00000</TotalMercanciasExentas>
        <TotalMercExonerada>0.00000</TotalMercExonerada>
        <TotalGravado>6398.75362</TotalGravado>
        <TotalExento>0.00000</TotalExento>
        <TotalExonerado>0.00000</TotalExonerado>
        <TotalVenta>6398.75362</TotalVenta>
        <TotalDescuentos>0.00000</TotalDescuentos>
        <TotalVentaNeta>6398.75362</TotalVentaNeta>
        <TotalImpuesto>831.83797</TotalImpuesto>
        <TotalOtrosCargos>111.97819</TotalOtrosCargos>
        <TotalComprobante>7342.56978</TotalComprobante>
    </ResumenFactura>
</FacturaElectronica>

I tried to create the billing class from a larger xml file, but it didn't work due to missing nodes. Since the class doesn't match the XML structure, it doesn't work with all files except the one I shared with you. I expect to open XML files of similar structure


Solution

  • Solved

    I had it with using the Visual Studio Auto Generated code. After a deep research I found the tool XSD.exe. With this tool I found out how to create a class from a XSD file. I needed to download linked schemas in order for it to work:

    First, I opened Developer Command Prompt for VS 2019, then I used CD commands to reach the files path, after that, i used the command:

    xsd /c {random_xsd_file}.xsd {another_rnd_xsd_file}.xsd

    With that, i created a .cs file containing all the classes needed. (If someone have any question feel free to ask, I spent lots of time researching this :p).