/// <summary> /// Valida la existencia de ciclos dentro de los linkbases y asegura que los ciclos existentes sean permitidos por el tipo de arco rol utilizado. /// </summary> private void ValidarCiclosEnLinkbases() { foreach (string rolUri in Taxonomia.ConjuntoArbolesLinkbase.Keys) { foreach (string rolLinkbase in Taxonomia.ConjuntoArbolesLinkbase[rolUri].Keys) { ArbolLinkbase arbol = Taxonomia.ConjuntoArbolesLinkbase[rolUri][rolLinkbase]; Debug.WriteLine("ValidadorAbaxXbrl: Validando ciclos de rol " + rolUri + " en linkbase " + rolLinkbase); //ImprimirNodo(0, arbol.NodoRaiz, new List<NodoLinkbase>()); if (rolLinkbase.Equals(LinkbasePresentacion.RolePresentacionLinkbaseRef)) { //Se valida que los arcos parent-child no tengan ciclos dirigidos if (arbol.TieneCiclosDirigidos(new List <string>() { ArcoPresentacion.RolArcoPresentacion })) { ManejadorErrores.ManejarError(null, "5.2.4.2 Un linkbase de presentación no debe contener ciclos dirigidos.", XmlSeverityType.Error); } } if (rolLinkbase.Equals(LinkbaseDefinicion.RolDefitionLinkbaseRef)) { //Se valida que los arcos general-special no tengan ciclos dirigidos if (arbol.TieneCiclosDirigidos(new List <string>() { ArcoDefinicion.GeneralSpecialRole })) { ManejadorErrores.ManejarError(null, "5.2.6.2.1 Los arcos del tipo http://www.xbrl.org/2003/arcrole/general-special no debe contener ciclos dirigidos.", XmlSeverityType.Error); } //se valida que los ciclos essence-alias no tengan ciclos dirigidos if (arbol.TieneCiclosDirigidos(new List <string>() { ArcoDefinicion.EssenceAliasRole })) { ManejadorErrores.ManejarError(null, "5.2.6.2.2 Los arcos del tipo http://www.xbrl.org/2003/arcrole/essence-alias no debe contener ciclos dirigidos.", XmlSeverityType.Error); } } //Validar los ciclos de los arcos roles personalizados únicamente en los linkbases estándar if (EtiquetasXBRLConstantes.ValidLinkBasesHref.Contains(rolLinkbase)) { foreach (ArcRoleType arcoPersonalizado in Taxonomia.ArcoRolesTaxonomia.Values) { if (!String.IsNullOrEmpty(arcoPersonalizado.CiclosPermitidos)) { //Se omiten en este validador los arcos dimension-domain y dimension-default if (!ArcosDimensionalesOmitidos(arcoPersonalizado)) { if (TiposCicloArco.Ninguno.Valor.Equals(arcoPersonalizado.CiclosPermitidos)) { if (arbol.TieneCiclos(new List <string>() { arcoPersonalizado.ArcoRolURI.ToString() }) || arbol.TieneCiclosDirigidos(new List <string>() { arcoPersonalizado.ArcoRolURI.ToString() })) { ManejadorErrores.ManejarError(null, "5.1.4.3 Los arcos personalizados del tipo " + arcoPersonalizado.ArcoRolURI.ToString() + " no debe contener ciclos.", XmlSeverityType.Error); } } else if (TiposCicloArco.NoDirigidos.Valor.Equals(arcoPersonalizado.CiclosPermitidos)) { if (arbol.TieneCiclosDirigidos(new List <string>() { arcoPersonalizado.ArcoRolURI.ToString() })) { ManejadorErrores.ManejarError(null, "5.1.4.3 Los arcos personalizados del tipo " + arcoPersonalizado.ArcoRolURI.ToString() + " no debe contener ciclos dirigidos.", XmlSeverityType.Error); } } } else { if (TiposCicloArco.Ninguno.Valor.Equals(arcoPersonalizado.CiclosPermitidos)) { if (arbol.TieneCiclosPorGrafo(new List <string>() { arcoPersonalizado.ArcoRolURI.ToString() }) || arbol.TieneCiclosDirigidos(new List <string>() { arcoPersonalizado.ArcoRolURI.ToString() })) { ManejadorErrores.ManejarError(null, "5.1.4.3 Los arcos personalizados del tipo " + arcoPersonalizado.ArcoRolURI.ToString() + " no debe contener ciclos.", XmlSeverityType.Error); } } else if (TiposCicloArco.NoDirigidos.Valor.Equals(arcoPersonalizado.CiclosPermitidos)) { if (arbol.TieneCiclosDirigidos(new List <string>() { arcoPersonalizado.ArcoRolURI.ToString() })) { ManejadorErrores.ManejarError(null, "5.1.4.3 Los arcos personalizados del tipo " + arcoPersonalizado.ArcoRolURI.ToString() + " no debe contener ciclos dirigidos.", XmlSeverityType.Error); } } } } } } } } }
public void TestCargaTaxonomia() { TaxonomiaXBRL taxonomiaXBRL = new TaxonomiaXBRL(); IManejadorErroresXBRL manejadorErrores = new ManejadorErroresCargaTaxonomia(); taxonomiaXBRL.ManejadorErrores = manejadorErrores; //Boolean correcto = taxonomiaXBRL.ProcesarDefinicionDeEsquemaRef("C:\\workspaces\\memoria_xbrl\\Ejercicio Práctico\\taxonomia1-2012-07-01-core.xsd"); //Boolean correcto = taxonomiaXBRL.ProcesarDefinicionDeEsquemaRef("C:\\dotNet\\AbaxXBRL_1\\AbaxXBRL\\XBRL-CONF-CR5-2012-01-24\\Common\\100-schema\\155-TypeExtension-Valid.xsd"); taxonomiaXBRL.ProcesarDefinicionDeEsquema(@"C:\taxonomy\mx-ifrs-2014-12-05\full_ifrs_mc_mx_ics_entry_point_2014-12-05.xsd"); taxonomiaXBRL.CrearArbolDeRelaciones(); XbrlViewerService serv = new XbrlViewerService(); var taxDt = serv.CrearTaxonomiaAPartirDeDefinicionXbrl(taxonomiaXBRL); var docServ = new DocumentoInstanciaService(); docServ.PerteneceConceptoAHipercuboEnRol("ifrs-full_ProfitLoss", taxDt, "http://bmv.com.mx/role/ifrs/ias_1_2014-03-05_role-610000"); foreach (RoleType tipoRol in taxonomiaXBRL.RolesTaxonomia.Values) { ArbolLinkbase arbolPresentation = taxonomiaXBRL.ConjuntoArbolesLinkbase[tipoRol.RolURI.ToString()][LinkbasePresentacion.RolePresentacionLinkbaseRef]; NodoLinkbase nodo = arbolPresentation.NodoRaiz; ImprimirNodo(0, nodo); Debug.WriteLine("________________________________________"); if (tipoRol.Linkbases.ContainsKey(LinkbaseReferencia.RoleReferenceLinkbaseRef)) { LinkbaseReferencia linkbase = (LinkbaseReferencia)tipoRol.Linkbases[LinkbaseReferencia.RoleReferenceLinkbaseRef]; foreach (Arco arco in linkbase.Arcos) { foreach (ElementoLocalizable elementoDesde in arco.ElementoDesde) { Concept conceptoDesde = (Concept)((Localizador)elementoDesde).Destino; foreach (ElementoLocalizable elementoHacia in arco.ElementoHacia) { Referencia referencia = (Referencia)elementoHacia.Destino; Debug.WriteLine(conceptoDesde.Elemento.Id + " Referencias: "); foreach (ReferenciaParte refPart in referencia.PartesReferencia) { Debug.WriteLine("\tReferencia:" + refPart.NombreLocal + " : " + refPart.Valor); } } } } } Debug.WriteLine("________________________________________"); if (tipoRol.Linkbases.ContainsKey(LinkbaseCalculo.RoleCalculoLinkbaseRef)) { LinkbaseCalculo linkbase = (LinkbaseCalculo)tipoRol.Linkbases[LinkbaseCalculo.RoleCalculoLinkbaseRef]; //Escribir los elementos que no tienen padre Debug.WriteLine(tipoRol.Id); IDictionary <string, string> impresos = new Dictionary <string, string>(); foreach (ArcoCalculo arco in linkbase.Arcos) { foreach (ElementoLocalizable elementoDesde in arco.ElementoDesde) { Concept conceptoDesde = (Concept)elementoDesde.Destino; if (!tienePadre(conceptoDesde, linkbase.Arcos)) { if (!impresos.ContainsKey(conceptoDesde.Elemento.Id)) { Debug.WriteLine(conceptoDesde.Elemento.Id); imprimirHijosCalculo(1, conceptoDesde.Elemento.Id, linkbase.Arcos, (LinkbaseCalculo)tipoRol.Linkbases[LinkbaseCalculo.RoleCalculoLinkbaseRef]); impresos[conceptoDesde.Elemento.Id] = conceptoDesde.Elemento.Id; } } } } } } Assert.IsTrue(true); }