Answering the questions:
1: I generated the class correctly by XSD.EXE?
Yes, that's right. Each information group needs to be a new class. And in the event that the group can occur more than once, you will have an array of objects of that class.
2: If yes, do I need to instantiate each class corresponding to the group to fill in the properties?
Yes, you do. Any property that is a "custom class" type, that is, refers to a new information group within the event structure, will come with null
value and you will need to explicitly create an object to "play this property."
Hint: Place each generated event class within a specific namespace, because all of them have the root element with the same name, Reinf
, and when you add the class of the second event already conflict if they are not in separate namespaces. You can put this first class in the R1000
namespace, for example:
namespace R1000 {
using System.Xml.Serialization;
public partial class Reinf {
public ReinfEvtInfoContri evtInfoContri;
}
// [...]
}
And the creation of the object of event R-1000 would look something like this:
// Elemento raiz EFD-Reinf.
var r1000 = new R1000.Reinf();
// Evento de informações do Contribuinte.
r1000.evtInfoContri = new R1000.ReinfEvtInfoContri();
// Identificação única do evento.
// Regra de validação: REGRA_VALIDA_ID_EVENTO
r1000.evtInfoContri.id = "ID2333901700001892014020213424700001";
// Informações de Identificação do Evento
r1000.evtInfoContri.ideEvento = new R1000.ReinfEvtInfoContriIdeEvento();
r1000.evtInfoContri.ideEvento.tpAmb = 2;
r1000.evtInfoContri.ideEvento.procEmi = 1;
r1000.evtInfoContri.ideEvento.verProc = "1";
// Informações de identificação do contribuinte
r1000.evtInfoContri.ideContri = new R1000.ReinfEvtInfoContriIdeContri();
r1000.evtInfoContri.ideContri.tpInsc = 1;
r1000.evtInfoContri.ideContri.nrInsc = "";
// Identificação da operação (inclusão, alteração ou exclusão) e das
// respectivas informações do Contribuinte.
r1000.evtInfoContri.infoContri = new R1000.ReinfEvtInfoContriInfoContri();
// Inclusão de novas informações
var inclusao = new R1000.ReinfEvtInfoContriInfoContriInclusao();
// Essa propriedade receberá um objeto de inclusão,
// mas poderia ser alteração ou exclusão também.
r1000.evtInfoContri.infoContri.Item = inclusao
// Período de validade das informações incluídas
inclusao.idePeriodo = new R1000.ReinfEvtInfoContriInfoContriInclusaoIdePeriodo();
inclusao.idePeriodo.iniValid = "2019-01";
//inclusao.idePeriodo.fimValid = "";
// Informações do Contribuinte
inclusao.infoCadastro = new R1000.ReinfEvtInfoContriInfoContriInclusaoInfoCadastro();
inclusao.infoCadastro.classTrib = "";
inclusao.infoCadastro.indEscrituracao = 0;
inclusao.infoCadastro.indDesoneracao = 0;
inclusao.infoCadastro.indAcordoIsenMulta = 0;
inclusao.infoCadastro.indSitPJ = 0;
// A ferramenta XSD.exe cria esses campos '{nomeDoCampo}Specified'
// no caso de campos opcionais, e aí você deve informar manualmente
// se o campo está sendo informado ou não.
inclusao.infoCadastro.indSitPJSpecified = true;
// Informações de contato
inclusao.infoCadastro.contato = new R1000.ReinfEvtInfoContriInfoContriInclusaoInfoCadastroContato();
inclusao.infoCadastro.contato.nmCtt = "";
inclusao.infoCadastro.contato.cpfCtt = "";
inclusao.infoCadastro.contato.foneFixo = "";
inclusao.infoCadastro.contato.foneCel = "";
inclusao.infoCadastro.contato.email = "";
// Informações da(s) empresa(s) desenvolvedora(s) da(s) aplicação(ões) que
// gera(m) os arquivos transmitidos para o ambiente nacional da EFD-Reinf.
//-------------------------------------------------------------------------
// Essa propriedade é um array, porque esse grupo pode ocorrer de 0 a 99 vezes.
inclusao.infoCadastro.softHouse = new R1000.ReinfEvtInfoContriInfoContriInclusaoInfoCadastroSoftHouse[]
{ new R1000.ReinfEvtInfoContriInfoContriInclusaoInfoCadastroSoftHouse()
{
cnpjSoftHouse = "";
nmRazao = "";
nmCont = "";
telefone = "";
email = "";
}
};
// [...]
Remembering that the r1000.evtInfoContri.id
field has a specific assembly rule, which you can check on page 43 of the Manual Developer Guide EFD-Reinf v1.3.03 :
3:HowwillIserializetheentireevent?sincethewholeeventiscomposedofseveralclasses.Itriedthatanditonlygeneratesthefirstblock.
Ithinkyoucanusethiscodeeventhoughyoupostedthequestion.ThegeneratedXMLonlyhadthefirstblockbecausethisistheonlyobjectpresentintheeventstructure,allothergroups/objectsareempty/null.Fromthemomenteverythingisfilledcorrectly,serializingeverythingwillappearinthegeneratedXML.
RememberingthattheXmlSerializer
classnormallyplacesthexmlns:xsi
andxmlns:xsd
attributesintherootelement,andaccordingtothedocumentation,thereshouldonlybethenamespaceofReinfitselfintherootelement.
HowtheXmlSerializer
classnormallygeneratesXML:
<?xml version="1.0" encoding="utf-8"?>
<Reinf xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.reinf.esocial.gov.br/schemas/evtInfoContribuinte/v1_04_00">
[...]
</Reinf>
How should it be:
<?xml version="1.0" encoding="utf-8"?>
<Reinf xmlns="http://www.reinf.esocial.gov.br/schemas/evtInfoContribuinte/v1_04_00">
[...]
</Reinf>
I use the following functions to serialize objects:
// Versão que serializa o objeto para o tipo XDocument.
public static XDocument SerializeToXDoc(object obj)
{
// O elemento raiz não pode conter os atributos 'xmlns:xsi' e 'xmlns:xsd',
// mas deve conter o atributo 'xmlns="http://www.reinf.esocial.gov.br/[...]'.
var ns = GetSerializerNamespace(obj);
var xDoc = new XDocument();
using (XmlWriter writer = xDoc.CreateWriter())
{
var xs = new XmlSerializer(obj.GetType());
xs.Serialize(writer, obj, ns);
}
return xDoc;
}
// Versão que serializa o objeto para o tipo XmlDocument.
public static XmlDocument SerializeToXmlDoc(object obj)
{
// O elemento raiz não pode conter os atributos 'xmlns:xsi' e 'xmlns:xsd',
// mas deve conter o atributo 'xmlns="http://www.reinf.esocial.gov.br/[...]'.
var ns = GetSerializerNamespace(obj);
var xmlDoc = new XmlDocument();
var nav = xmlDoc.CreateNavigator();
using (XmlWriter writer = nav.AppendChild())
{
var xs = new XmlSerializer(obj.GetType());
xs.Serialize(writer, obj, ns);
}
return xmlDoc;
}
private static XmlSerializerNamespaces GetSerializerNamespace(object obj)
{
// Pega o namespace definido para a classe que se deseja serializar, pelo atributo XML.
// Exemplo: 'xmlns="http://www.reinf.esocial.gov.br/[...]'.
var xmlAttrib = (XmlTypeAttribute) Attribute.GetCustomAttribute(obj.GetType(),
typeof(XmlTypeAttribute));
string nsClasse = xmlAttrib?.Namespace ?? "";
// Informa que o elemento raiz do XML que será gerado não deve incluir os atributos
// 'xmlns:xsi' e 'xmlns:xsd', mas deve incluir o namespace da classe que se deseja serializar.
var ns = new XmlSerializerNamespaces();
ns.Add("", nsClasse);
return ns;
}