0

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>facturacion@callmyway.com</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

jdweng
  • 33,250
  • 2
  • 15
  • 20
  • Please add some other XML files noting the differences that you are writing about. – Tu deschizi eu inchid Nov 07 '22 at 23:03
  • The following may (or may not) be helpful: https://stackoverflow.com/a/73640395/10024425 – Tu deschizi eu inchid Nov 07 '22 at 23:04
  • 1
    You have a complicated xml that has a schema. Contact organization that owns the schema and get version that is compatible with your version of xml. Then use XSD tool (or equivalent) to automatically generate the c# classes. If xml doesn't match schema than contact people who created the xml and have them fix the xml. XML files must be validated against a schema before sending to users. I've seen too many cases where xml contain errors and then sent to user community. – jdweng Nov 08 '22 at 04:09
  • 2
    You can manually create the c# classes for any xml file, but where you are using an xml that is controlled by an organization that has a schema you should always use the schema. There are reasons organizations maintain schemas so developers and users can share data. – jdweng Nov 08 '22 at 04:13
  • The thing is, I'm using a government-provided schema for developers(There is only 1 schema available), and there may be thousands of versions that differ by more or fewer nodes than the actual schema(Depends on store needs). All of these XMLs are approved by the organization (even though they are different, which is odd). – Josué Campos Nov 08 '22 at 14:32
  • Remove the extra nodes before deserialization? – Magnus Nov 08 '22 at 16:39

1 Answers1

1

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).