private void ImprimirNodo(int nivel, NodoLinkbase nodo, List <NodoLinkbase> impresos)
        {
            if (nivel > 50)
            {
                return;
            }
            if (impresos.Count(nod => nod == nodo) > 1)
            {
                return;
            }
            //Imprimir este nodo en el nivel
            int espacios = nivel * 5;

            for (int i = 0; i < espacios; i++)
            {
                Debug.Write(" ");
            }

            Debug.WriteLine(nodo.Elemento.Id);
            impresos.Add(nodo);
            foreach (ConectorLinkbase conn in nodo.ConectoresSalientes)
            {
                ImprimirNodo(nivel + 1, conn.NodoSiguiente, impresos);
            }
        }
        /// <summary>
        /// Recorre el árbol en busca de la definición de hipercubos y para cada declaración
        /// recorre el subárbol del hipercubo buscando ciclos dirigidos
        /// </summary>
        /// <param name="nodo">Nodo actualemnte verificado</param>
        /// <returns>True si existe algún ciclo dirigido de hipercubo en el nodo</returns>
        private bool ValidarCiclosDirigidosEnHipercubos(NodoLinkbase nodo, IList <ElementoXBRL> nodosVisitadosPrincipal)
        {
            bool existeCiclo = false;



            foreach (var conector in nodo.ConectoresSalientes)
            {
                if (conector.Arco != null && (conector.Arco.ArcoRol.Equals(ArcoDefinicion.HasHypercubeAllRole) || conector.Arco.ArcoRol.Equals(ArcoDefinicion.HasHypercubeNotAllRole)))
                {
                    //Se encontró la declaración de un cubo, validar ciclos
                    IList <ConceptItem> nodosVisitados = new List <ConceptItem>();
                    if (ExisteCicloEnHipercubo(nodosVisitados, nodo, conector))
                    {
                        existeCiclo = true;
                        break;
                    }
                }
                if (nodosVisitadosPrincipal.Contains(nodo.Elemento))
                {
                    return(false);
                }
                nodosVisitadosPrincipal.Add(nodo.Elemento);
                if (ValidarCiclosDirigidosEnHipercubos(conector.NodoSiguiente, nodosVisitadosPrincipal))
                {
                    existeCiclo = true;
                    break;
                }
            }
            nodosVisitadosPrincipal.Remove(nodo.Elemento);
            return(existeCiclo);
        }
示例#3
0
 /// <summary>
 /// Recorre el arbol de relaciones dimensionales en busca de elemento primarios, los agrega a la lista de elementos primarios
 /// </summary>
 /// <param name="nodoActual"></param>
 private void LlenarElementosPrimarios(NodoLinkbase nodoActual)
 {
     foreach (var conector in nodoActual.ConectoresSalientes.Where(x => x.Arco.ArcoRol.Equals(ArcoDefinicion.DomainMemberRole)))
     {
         if (!_elementosPrimarios.Contains(conector.NodoSiguiente.Elemento))
         {
             _elementosPrimarios.Add(conector.NodoSiguiente.Elemento as ConceptItem);
             LlenarElementosPrimarios(conector.NodoSiguiente);
         }
     }
 }
        private void ImprimirNodo(int nivel, NodoLinkbase nodo)
        {
            //Imprimir este nodo en el nivel
            int espacios = nivel * 5;

            for (int i = 0; i < espacios; i++)
            {
                Debug.Write(" ");
            }
            Debug.WriteLine(nodo.Elemento.Id);
            foreach (ConectorLinkbase conn in nodo.ConectoresSalientes)
            {
                ImprimirNodo(nivel + 1, conn.NodoSiguiente);
            }
        }
示例#5
0
        /// <summary>
        /// Colecta los miembros válidos de dominio de dimensiones
        /// </summary>
        /// <param name="dimension">Declaración de la dimensión</param>
        /// <param name="nodoActual"> </param>
        /// <param name="tax"> </param>
        private void LlenarDominioDeDimension(Dimension dimension, NodoLinkbase nodoActual, ITaxonomiaXBRL tax)
        {
            IList <string> arcoRolesBuscados = new List <string>()
            {
                ArcoDefinicion.DimensionDomainRole, ArcoDefinicion.DomainMemberRole
            };

            foreach (var conectorSiguiente in nodoActual.ConectoresSalientes.Where(x => x.Arco != null && arcoRolesBuscados.Contains(x.Arco.ArcoRol)))
            {
                //considerar el atributo usable
                if (!((conectorSiguiente.Arco as ArcoDefinicion).Usable != null && !(conectorSiguiente.Arco as ArcoDefinicion).Usable.Value))
                {
                    if (!dimension.MiembrosDominio.Contains(conectorSiguiente.NodoSiguiente.Elemento))
                    {
                        dimension.MiembrosDominio.Add(conectorSiguiente.NodoSiguiente.Elemento as ConceptItem);
                    }
                }
                else
                {
                    if (!dimension.MiembrosDominioNoUsables.Contains(conectorSiguiente.NodoSiguiente.Elemento))
                    {
                        dimension.MiembrosDominioNoUsables.Add(conectorSiguiente.NodoSiguiente.Elemento as ConceptItem);
                    }
                }
                LlenarDominioDeDimension(dimension, conectorSiguiente.NodoSiguiente, tax);
            }
            if (!dimension.Explicita)
            {
                //Localizar el schema element de la dimensión
                if (dimension.ConceptoDimension.ReferenciaDimensionTipificada != null)
                {
                    foreach (var esquema in tax.ArchivosEsquema.Where(x => x.Key.Equals(dimension.ConceptoDimension.ReferenciaDimensionTipificada.UbicacionArchivo)))
                    {
                        foreach (XmlSchemaElement unElemento in esquema.Value.Elements.Values)
                        {
                            if (unElemento.Id != null && unElemento.Id.Equals(dimension.ConceptoDimension.ReferenciaDimensionTipificada.Identificador))
                            {
                                dimension.ConceptoDimension.ElementoDimensionTipificada = unElemento;
                                break;
                            }
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Realiza el recorrido de un hipercubo validando si ya se ha visitado algún nodo realizando un recorrido ordenado
 /// </summary>
 /// <param name="nodosVisitados"></param>
 /// <param name="nodo"></param>
 /// <param name="conectorOrigen"></param>
 private bool ExisteCicloEnHipercubo(IList <ConceptItem> nodosVisitados, NodoLinkbase nodo, ConectorLinkbase conectorOrigen)
 {
     if (nodosVisitados.Contains(nodo.Elemento))
     {
         //Error
         return(true);
     }
     nodosVisitados.Add(nodo.Elemento as ConceptItem);
     foreach (var conectorActual in nodo.ConectoresSalientes.Where(x => x.Arco != null && ArcoDefinicion.RolesArcosDimensionalesConsecutivos.ContainsKey(x.Arco.ArcoRol)))
     {
         if (ExisteCicloEnHipercubo(nodosVisitados, conectorActual.NodoSiguiente, conectorOrigen))
         {
             return(true);
         }
     }
     nodosVisitados.Remove(nodo.Elemento as ConceptItem);
     return(false);
 }
示例#7
0
        /// <summary>
        /// Constructor básico, se necesita un nodo con la declaración del elemento primario para inicial el hipercubo
        /// </summary>
        /// <param name="nodoOrigen"></param>
        public Hipercubo(NodoLinkbase nodoOrigen, ConectorLinkbase conectorInicial, RoleType rol, IDictionary <ConceptDimensionItem, ConceptItem> listaDimensionesDefault, ITaxonomiaXBRL tax)
        {
            ListaDimensiones = new List <Dimension>();
            Rol = rol;
            DeclaracionElementoPrimario = nodoOrigen;
            //Elementos primarios
            _elementosPrimarios.Add(nodoOrigen.Elemento as ConceptItem);
            LlenarElementosPrimarios(nodoOrigen);
            //Determinar el tipo de elemento en el contexto donde aparece la información dimensional del hipercubo
            ElementoContexto = (conectorInicial.Arco as ArcoDefinicion).ElementoContexto;
            //Atributo cerrado
            Cerrado = (conectorInicial.Arco as ArcoDefinicion).Closed != null
                          ? (conectorInicial.Arco as ArcoDefinicion).Closed.Value
                          : false;
            ArcRoleDeclaracion = conectorInicial.Arco.ArcoRol;

            ElementoHipercubo = conectorInicial.NodoSiguiente;
            //Dimensiones
            foreach (var conectoresDimension in ElementoHipercubo.ConectoresSalientes.Where(x => x.Arco.ArcoRol.Equals(ArcoDefinicion.HypercubeDimensionRole)))
            {
                var dimDec = new Dimension();

                dimDec.ConceptoDimension = conectoresDimension.NodoSiguiente.Elemento as ConceptDimensionItem;
                dimDec.Explicita         = dimDec.ConceptoDimension.ReferenciaDimensionTipificada == null;
                ListaDimensiones.Add(dimDec);
                foreach (var dimDefault in listaDimensionesDefault.Where(x => x.Key == conectoresDimension.NodoSiguiente.Elemento))
                {
                    if (!_dimensionDefaults.ContainsKey(dimDefault.Key))
                    {
                        _dimensionDefaults.Add(dimDefault.Key, dimDefault.Value);
                        dimDec.MiembroDefault = dimDefault.Value;
                    }
                }
                //Llenar dominio de dimensión
                LlenarDominioDeDimension(dimDec, conectoresDimension.NodoSiguiente, tax);
                //Quitar del dominio a los elementos no usables que pudieran quedar repetidos
                foreach (var noUsable in dimDec.MiembrosDominioNoUsables)
                {
                    dimDec.MiembrosDominio.Remove(noUsable);
                }
            }
        }
 /// <summary>
 /// Recorre el árbol en busca de la definición de hipercubos y para cada hipercubo validar que sus primary items no sean
 /// parte de los miembros válidos de las dimensiones del hipercubo
 /// </summary>
 /// <param name="nodo">Nodo actualmente verificado</param>
 /// <param name="elementoXbrls"> </param>
 private void ValidarPrimaryItemEnMiembrosValidos(NodoLinkbase nodo, IList <ElementoXBRL> nodosVisitados)
 {
     if (nodosVisitados.Contains(nodo.Elemento))
     {
         return;
     }
     nodosVisitados.Add(nodo.Elemento);
     foreach (var conector in nodo.ConectoresSalientes)
     {
         if (conector.Arco != null && (conector.Arco.ArcoRol.Equals(ArcoDefinicion.HasHypercubeAllRole) || conector.Arco.ArcoRol.Equals(ArcoDefinicion.HasHypercubeNotAllRole)))
         {
             //Se encontró la declaración de un cubo, obtener sus elementos primarios en forma de lista
             IList <ConceptItem> elementosPrimarios = new List <ConceptItem>();
             ObtenerListaElementosPrimarios(elementosPrimarios, nodo);
             VerificarElementoPrimarioEnMiembro(elementosPrimarios, conector.NodoSiguiente, conector);
         }
         ValidarPrimaryItemEnMiembrosValidos(conector.NodoSiguiente, nodosVisitados);
     }
     nodosVisitados.Remove(nodo.Elemento);
 }
 /// <summary>
 /// Colecta una lista de elementos partiendo del nodo origen que estén relacionados por arcos domain-member
 /// </summary>
 /// <param name="nodo">Nodo origen</param>
 private void ObtenerListaElementosPrimarios(IList <ConceptItem> elementosPrimarios, NodoLinkbase nodo)
 {
     if (elementosPrimarios.Contains(nodo.Elemento))
     {
         return;
     }
     elementosPrimarios.Add(nodo.Elemento as ConceptItem);
     foreach (var conector in nodo.ConectoresSalientes.Where(x => x.Arco != null && x.Arco.ArcoRol.Equals(ArcoDefinicion.DomainMemberRole)))
     {
         ObtenerListaElementosPrimarios(elementosPrimarios, conector.NodoSiguiente);
     }
 }
 /// <summary>
 /// Verifica si los elementos primarios existen también como miembros válidos de las dimensiones de un cubo,
 /// notifica un error en caso de encontrar coincidencias
 /// </summary>
 /// <param name="elementosPrimarios">Lista de elementos primarios</param>
 /// <param name="nodo">Nodo origen</param>
 /// <param name="conectorOrigenHipercubo">Conector origen del hipercubo</param>
 /// <param name="miembroUsable">Indica si el miembro de la dimensión es usable de acuerdo a su arco antecesor</param>
 private void VerificarElementoPrimarioEnMiembro(IList <ConceptItem> elementosPrimarios, NodoLinkbase nodo, ConectorLinkbase conectorOrigenHipercubo, bool miembroUsable = true)
 {
     if (miembroUsable && elementosPrimarios.Contains(nodo.Elemento))
     {
         ManejadorErrores.ManejarError(CodigosErrorXBRL.PrimaryItemPolymorphismError, null,
                                       "2.5.3.1.1.3 Se encontró un conjunto de arcos que relacionan elementos que definen un hipercubo donde fue detectado un ciclo: Hipercubo: " +
                                       conectorOrigenHipercubo.NodoSiguiente.Elemento.Id,
                                       XmlSeverityType.Error);
     }
     foreach (var conector in nodo.ConectoresSalientes.Where(x => x.Arco != null &&
                                                             (x.Arco.ArcoRol.Equals(ArcoDefinicion.HypercubeDimensionRole) || x.Arco.ArcoRol.Equals(ArcoDefinicion.DimensionDomainRole) || x.Arco.ArcoRol.Equals(ArcoDefinicion.DomainMemberRole))))
     {
         VerificarElementoPrimarioEnMiembro(elementosPrimarios, conector.NodoSiguiente, conectorOrigenHipercubo, (conector.Arco as ArcoDefinicion).Usable != null?
                                            (conector.Arco as ArcoDefinicion).Usable.Value:true);
     }
 }
        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);
        }