NFe XML decapsulation

2

Well, I'm trying to read for importing% of Electronic Bills and I'm having a hard time decapsulating the XMLs of blessed.

No problem getting to the object ICMS :

object objeto = ListaItens[i].imposto.Items[0]

This returns an object of type ICMS and here is the description of this class:

public partial class TNFeInfNFeDetImpostoICMS {

    private object itemField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("ICMS00", typeof(TNFeInfNFeDetImpostoICMSICMS00))]
    [System.Xml.Serialization.XmlElementAttribute("ICMS10", typeof(TNFeInfNFeDetImpostoICMSICMS10))]
    [System.Xml.Serialization.XmlElementAttribute("ICMS20", typeof(TNFeInfNFeDetImpostoICMSICMS20))]
    [System.Xml.Serialization.XmlElementAttribute("ICMS30", typeof(TNFeInfNFeDetImpostoICMSICMS30))]
    [System.Xml.Serialization.XmlElementAttribute("ICMS40", typeof(TNFeInfNFeDetImpostoICMSICMS40))]
    [System.Xml.Serialization.XmlElementAttribute("ICMS51", typeof(TNFeInfNFeDetImpostoICMSICMS51))]
    [System.Xml.Serialization.XmlElementAttribute("ICMS60", typeof(TNFeInfNFeDetImpostoICMSICMS60))]
    [System.Xml.Serialization.XmlElementAttribute("ICMS70", typeof(TNFeInfNFeDetImpostoICMSICMS70))]
    [System.Xml.Serialization.XmlElementAttribute("ICMS90", typeof(TNFeInfNFeDetImpostoICMSICMS90))]
    [System.Xml.Serialization.XmlElementAttribute("ICMSPart", typeof(TNFeInfNFeDetImpostoICMSICMSPart))]
    [System.Xml.Serialization.XmlElementAttribute("ICMSSN101", typeof(TNFeInfNFeDetImpostoICMSICMSSN101))]
    [System.Xml.Serialization.XmlElementAttribute("ICMSSN102", typeof(TNFeInfNFeDetImpostoICMSICMSSN102))]
    [System.Xml.Serialization.XmlElementAttribute("ICMSSN201", typeof(TNFeInfNFeDetImpostoICMSICMSSN201))]
    [System.Xml.Serialization.XmlElementAttribute("ICMSSN202", typeof(TNFeInfNFeDetImpostoICMSICMSSN202))]
    [System.Xml.Serialization.XmlElementAttribute("ICMSSN500", typeof(TNFeInfNFeDetImpostoICMSICMSSN500))]
    [System.Xml.Serialization.XmlElementAttribute("ICMSSN900", typeof(TNFeInfNFeDetImpostoICMSICMSSN900))]
    [System.Xml.Serialization.XmlElementAttribute("ICMSST", typeof(TNFeInfNFeDetImpostoICMSICMSST))]
    public object Item {
        get {
            return this.itemField;
        }
        set {
            this.itemField = value;
        }
    }
}

What I would like to do is to scan all "types" of TNFeInfNFeDetImpostoICMS to get their properties, but I do not find any way to loop ICMS by uncapping each element.

Can you help?

for

One thing I realized in practice (I do not have a lot of fiscal knowledge) is that every item in EDIT: will only contain one of these XML encapsulated classes, so you only need to find a way for the program to do ICMS of the object by choosing at runtime the contained class. Is there any way to do this?

unbox

I perform deserialization as follows:

I have a class EDIT2: :

public static class Serializer
    {
        public static T Deserialize<T>(this XElement xElement) 
        {
            using (var memoryStream = new MemoryStream(Encoding.ASCII.GetBytes(xElement.ToString())))
            {
                var xmlSerializer = new XmlSerializer(typeof(T));
                return (T)xmlSerializer.Deserialize(memoryStream);
            }
        }

        public static XElement Serialize<T>(this object o)
        {
            using (var memoryStream = new MemoryStream())
            {
                using (TextWriter streamWriter = new StreamWriter(memoryStream))
                {
                    var xmlSerializer = new XmlSerializer(typeof(T));
                    xmlSerializer.Serialize(streamWriter, o);
                    return XElement.Parse(Encoding.ASCII.GetString(memoryStream.ToArray()));
                }
            }
        }
    }

And a Serializer class generated from ProcNFe_v3_10 that I got on the farm site (I will not post because it is too long).

Then first I load a .xsd with my XElement :

XElement xElement = XElement.Load(ofdXml.FileName);

Being .xml a ofdXml .

And then I call the OpenFileDialog method of my class passing deserializer to type TNfeProc (which is the corresponding type of my note contained within the T class) and ProcNFe_v3_10 loaded as an attribute, as follows:

TNfeProc NFCarregada = Serializer.Deserialize<TNfeProc>(xElement);

And voilà, I have my xElement deserialized.

    
asked by anonymous 18.03.2015 / 21:24

2 answers

1

Here's a solution:

static void Main(string[] args)
    {
        string fileName = "c:\temp\arquivo.xml";
        var nfe = XElement.Load(fileName);
        var nfeCarregada = Serializer.Deserialize<TNfeProc>(nfe);

        var imp = nfeCarregada.NFe.infNFe.det.Select(x => x.imposto);
        foreach (var imposto in imp)
        {
            if (imposto.PIS.Item.GetType().Name == "TNFeInfNFeDetImpostoPISPISNT")
            {
                var pisNT = (TNFeInfNFeDetImpostoPISPISNT)imposto.PIS.Item;
                Console.WriteLine(String.Format("PISNT: \nCST:{0}",  pisNT.CST));
            }
            else if (imposto.PIS.Item.GetType().Name == "TNFeInfNFeDetImpostoPISPISAliq")
            {
                var pisAliq = (TNFeInfNFeDetImpostoPISPISAliq)imposto.PIS.Item;
                Console.WriteLine(String.Format("PISAliq: CST:{0}\nvBC:{1}\nvPIS:{2}", pisAliq.CST, pisAliq.vBC, pisAliq.vPIS));
            }//CONTINUA

            if (imposto.COFINS.Item.GetType().Name == "TNFeInfNFeDetImpostoCOFINSCOFINSNT")
            {
                var cofins = (TNFeInfNFeDetImpostoCOFINSCOFINSNT)imposto.COFINS.Item;
                Console.WriteLine(String.Format("COFINS: \nCST:{0}", cofins.CST));
            }//CONTINUA

            foreach (var itemImposto in imposto.Items.Select(x => x.Serialize<TNFeInfNFeDetImpostoICMS>()))
            {
                var tipoICMS = itemImposto.Elements().ElementAtOrDefault(0).Name.LocalName;
                if (tipoICMS.ToString() == "ICMS60")
                {
                    var icms = (TNFeInfNFeDetImpostoICMSICMS60)Serializer.Deserialize<TNFeInfNFeDetImpostoICMS>(itemImposto).Item;
                    Console.WriteLine(string.Format("CST {0} ORIGEM {1}", icms.CST, icms.orig));
                }
                else if (tipoICMS.ToString() == "ICMS00")
                {
                    var icms = (TNFeInfNFeDetImpostoICMSICMS00)Serializer.Deserialize<TNFeInfNFeDetImpostoICMS>(itemImposto).Item;
                    Console.WriteLine(string.Format("ICMS00:\nCST {0} \norig {1} \nmodBC {2} \npICMS {3} \nvBC {4} \nvICMS {5}",
                        icms.CST, icms.orig, icms.modBC, icms.pICMS, icms.vBC, icms.vICMS));
                }//..continua
            }
        }
    }

Result:

Note:Icannotdeserialize"item" (see image field CST) if you can get the values of these fields please share this code:).

    
22.03.2015 / 04:13
0

I ended up using a for to scan the content of Item and a Switch to select the correct class (which I thought was a pretty bad service, by the way):

string porcICMS;
string porcIPI;
for (int j = 0; j < (ListaItens[i].imposto.Items.Length); j++)
{
    switch (ListaItens[i].imposto.Items[j].GetType().ToString())
    {
        case "TNFeInfNFeDetImpostoICMS": 
            object ICMS = (((TNFeInfNFeDetImpostoICMS)(ListaItens[i].imposto.Items[j])).Item);

            switch (ICMS.GetType().ToString())
            {
                case "TNFeInfNFeDetImpostoICMSICMS00": porcICMS = ((TNFeInfNFeDetImpostoICMSICMS00)ICMS).pICMS;
                    break;
                case "TNFeInfNFeDetImpostoICMSICMS10": porcICMS = ((TNFeInfNFeDetImpostoICMSICMS10)ICMS).pICMS;
                    break;
                case "TNFeInfNFeDetImpostoICMSICMS20": porcICMS = ((TNFeInfNFeDetImpostoICMSICMS20)ICMS).pICMS;
                    break;
                case "TNFeInfNFeDetImpostoICMSICMS51": porcICMS = ((TNFeInfNFeDetImpostoICMSICMS51)ICMS).pICMS;
                    break;
                case "TNFeInfNFeDetImpostoICMSICMS60": porcICMS = ((TNFeInfNFeDetImpostoICMSICMS60)ICMS).vICMSSTRet;
                    break;
                case "TNFeInfNFeDetImpostoICMSICMS70": porcICMS = ((TNFeInfNFeDetImpostoICMSICMS70)ICMS).pICMS;
                    break;
                case "TNFeInfNFeDetImpostoICMSICMS90": porcICMS = ((TNFeInfNFeDetImpostoICMSICMS90)ICMS).pICMS;
                    break;
                case "TNFeInfNFeDetImpostoICMSICMSPart": porcICMS = ((TNFeInfNFeDetImpostoICMSICMSPart)ICMS).pICMS;
                    break;
            }
            break;

        case "TIpi":
            object IPI = (((TIpi)(ListaItens[i].imposto.Items[j])).Item);
            porcIPI = ((TIpiIPITrib)IPI).Items[1];
            break;

        default:
            porcICMS = "0.0000";
            porcIPI = "0.0000";
            break;
    }
}

But it worked. In IPI there is still another Item object that used Item[1] , which corresponds to the percentage.

Again, it seems to me to be an amateur service that I did. If you have another solution, share it.

    
24.03.2015 / 15:52