def propertyView(self): if self.isExplicit: return (unicode(self.dimensionQname),unicode(self.memberQname)) else: return (unicode(self.dimensionQname), XmlUtil.xmlstring( self.typedMember, stripXmlns=True, prettyPrint=True ) if isinstance(self.typedMember, ModelObject) else u"None" )
def propertyView(self): if self.isExplicit: return (str(self.dimensionQname),str(self.memberQname)) else: return (str(self.dimensionQname), XmlUtil.xmlstring( self.typedMember, stripXmlns=True, prettyPrint=True ) if self.typedMember is not None else "None" )
def propertyView(self): if self.isExplicit: return (str(self.dimensionQname),str(self.memberQname)) else: return (str(self.dimensionQname), XmlUtil.xmlstring( self.typedMember, stripXmlns=True, prettyPrint=True ) if isinstance(self.typedMember, ModelObject) else "None" )
def factAspectValue(fact, aspect, view=False): if aspect == Aspect.LOCATION: parentQname = fact.getparent().qname if parentQname == XbrlConst.qnXbrliXbrl: # not tuple return NONE return parentQname # tuple elif aspect == Aspect.CONCEPT: return fact.qname elif fact.isTuple or fact.context is None: return NONE #subsequent aspects don't exist for tuples elif aspect == Aspect.UNIT: if fact.unit is None: return NONE measures = fact.unit.measures if measures[1]: return "{0} / {1}".format(' '.join(str(m) for m in measures[0]), ' '.join(str(m) for m in measures[1])) else: return ' '.join(str(m) for m in measures[0]) else: context = fact.context if aspect == Aspect.PERIOD: return ("forever" if context.isForeverPeriod else XmlUtil.dateunionValue(context.instantDatetime, subtractOneDay=True) if context.isInstantPeriod else XmlUtil.dateunionValue(context.startDatetime) + "-" + XmlUtil.dateunionValue(context.endDatetime, subtractOneDay=True)) elif aspect == Aspect.ENTITY_IDENTIFIER: if view: return context.entityIdentifier[1] else: return context.entityIdentifier # (scheme, identifier) elif aspect in (Aspect.COMPLETE_SEGMENT, Aspect.COMPLETE_SCENARIO, Aspect.NON_XDT_SEGMENT, Aspect.NON_XDT_SCENARIO): return ''.join(XmlUtil.xmlstring(elt, stripXmlns=True, prettyPrint=True) for elt in context.nonDimValues(aspect))
def factAspectValue(fact, aspect, view=False): if fact is DEFAULT: return 'none' elif fact is NONDEFAULT: return '*' elif fact is DEFAULTorNONDEFAULT: return '**' elif aspect == Aspect.LOCATION: parentQname = fact.getparent().qname if parentQname == XbrlConst.qnXbrliXbrl: # not tuple return NONE return parentQname # tuple elif aspect == Aspect.CONCEPT: return fact.qname elif fact.isTuple or fact.context is None: return NONE #subsequent aspects don't exist for tuples elif aspect == Aspect.UNIT: if fact.unit is None: return NONE measures = fact.unit.measures if measures[1]: return "{0} / {1}".format(' '.join(str(m) for m in measures[0]), ' '.join(str(m) for m in measures[1])) else: return ' '.join(str(m) for m in measures[0]) else: context = fact.context if aspect == Aspect.PERIOD: return ("forever" if context.isForeverPeriod else XmlUtil.dateunionValue(context.instantDatetime, subtractOneDay=True) if context.isInstantPeriod else XmlUtil.dateunionValue(context.startDatetime) + "-" + XmlUtil.dateunionValue(context.endDatetime, subtractOneDay=True)) elif aspect == Aspect.ENTITY_IDENTIFIER: if view: return context.entityIdentifier[1] else: return context.entityIdentifier # (scheme, identifier) elif aspect in (Aspect.COMPLETE_SEGMENT, Aspect.COMPLETE_SCENARIO, Aspect.NON_XDT_SEGMENT, Aspect.NON_XDT_SCENARIO): return ''.join(XmlUtil.xmlstring(elt, stripXmlns=True, prettyPrint=True) for elt in context.nonDimValues(aspect)) elif aspect == Aspect.DIMENSIONS: return context.dimAspects(fact.xpCtx.defaultDimensionAspects) elif isinstance(aspect, QName): dimValue = context.dimValue(aspect) if dimValue is None: return NONE else: if isinstance(dimValue, QName): #default dim return dimValue elif dimValue.isExplicit: return dimValue.memberQname else: # explicit return dimValue.typedMember.xValue # typed element value
def doObject(self, fObj, fromRel, pIndent, visited): if fObj is None: return cIndent = pIndent + " " if isinstance(fObj, ModelAssertionSet): self.xf = "{}assertion-set {} {{".format(pIndent, self.objectId(fObj, "assertionSet")) for modelRel in self.modelXbrl.relationshipSet(XbrlConst.assertionSet).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, cIndent, visited) self.xf = "{}}};".format(pIndent) elif isinstance(fObj, (ModelValueAssertion, ModelExistenceAssertion, ModelFormula)): varSetType = "formula" if isinstance(fObj, ModelFormula) else "assertion" self.xf = "{}{} {} {{".format(pIndent, varSetType, self.objectId(fObj, varSetType)) for arcrole in (XbrlConst.elementLabel, XbrlConst.assertionSatisfiedMessage, XbrlConst.assertionUnsatisfiedMessage): for modelRel in self.modelXbrl.relationshipSet(arcrole).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, cIndent, visited) if fObj.aspectModel == "non-dimensional": self.xf = "{}aspect-model-non-dimensional;".format(cIndent) if fObj.implicitFiltering == "false": self.xf = "{}no-implicit-filtering;".format(cIndent) if isinstance(fObj, ModelFormula): for attr in ("decimals", "precision", "value"): if fObj.get(attr): self.xf = "{}{} {{{}}};".format(cIndent, attr, fObj.get(attr)) if fObj.get("source"): self.xf = "{}source {};".format(cIndent, fObj.get("source")) for aspectsElt in XmlUtil.children(fObj, XbrlConst.formula, "aspects"): self.xf = "{}aspect-rules{} {{".format(cIndent, "source {}".format(aspectsElt.get("source")) if aspectsElt.get("source") else "") for ruleElt in XmlUtil.children(aspectsElt, XbrlConst.formula, "*"): self.doObject(ruleElt, None, cIndent + " ", visited) self.xf = "{}}};".format(cIndent) for arcrole in (XbrlConst.variableSetFilter, XbrlConst.variableSet, XbrlConst.variableSetPrecondition): for modelRel in self.modelXbrl.relationshipSet(arcrole).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, cIndent, visited) if isinstance(fObj, ModelValueAssertion): self.xf = "{}test {{{}}};".format(cIndent, fObj.viewExpression) elif isinstance(fObj, ModelExistenceAssertion): self.xf = "{}evaluation-count {{{}}};".format(cIndent, fObj.viewExpression or ". gt 0") self.xf = "{}}};".format(pIndent) elif isinstance(fObj, ModelConsistencyAssertion): self.xf = "{}consistency-assertion {} {{".format(pIndent, self.objectId(fObj, "consistencyAssertion")) for arcrole in (XbrlConst.elementLabel, XbrlConst.assertionSatisfiedMessage, XbrlConst.assertionUnsatisfiedMessage): for modelRel in self.modelXbrl.relationshipSet(arcrole).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, cIndent, visited) if fObj.isStrict: self.xf = "{}strict;".format(cIndent) if fObj.get("proportionalAcceptanceRadius"): self.xf = "{}proportional-acceptance-radius {{{}}};".format(cIndent, fObj.get("proportionalAcceptanceRadius")) if fObj.get("absoluteAcceptanceRadius"): self.xf = "{}absolute-acceptance-radius {{{}}};".format(cIndent, fObj.get("absoluteAcceptanceRadius")) for modelRel in self.modelXbrl.relationshipSet(XbrlConst.consistencyAssertionFormula).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, cIndent, visited) self.xf = "{}}};".format(pIndent) elif isinstance(fObj, ModelFactVariable) and fromRel is not None: self.xf = "{}variable ${} {{".format(pIndent, fromRel.variableQname) if fromRel.variableQname.prefix: self.xmlns[fromRel.variableQname.prefix] = fromRel.variableQname.namespaceURI if fObj.bindAsSequence == "true": self.xf = "{}bind-as-sequence".format(cIndent) if fObj.nils == "true": self.xf = "{}nils".format(cIndent) if fObj.matches == "true": self.xf = "{}matches".format(cIndent) if fObj.fallbackValue: self.xf = "{}fallback {{{}}}".format(cIndent, fObj.fallbackValue) for modelRel in self.modelXbrl.relationshipSet(XbrlConst.variableFilter).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, cIndent, visited) self.xf = "{}}};".format(pIndent) elif isinstance(fObj, ModelGeneralVariable) and fromRel is not None: self.xf = "{}variable ${} {{".format(pIndent, fromRel.variableQname) if fromRel.variableQname.prefix: self.xmlns[fromRel.variableQname.prefix] = fromRel.variableQname.namespaceURI if fObj.bindAsSequence: self.xf = "{}bind-as-sequence".format(cIndent) self.xf = "{}select {{{}}}".format(cIndent, fObj.select) elif isinstance(fObj, ModelParameter): if fromRel is not None: # parameter is referenced by a different QName on arc if fromRel.variableQname.prefix: self.xmlns[fromRel.variableQname.prefix] = fromRel.variableQname.namespaceURI self.xf = "{}parameter ${} references ${};".format(pIndent, fromRel.variableQname, fObj.parameterQname) else: # root level parameter if fObj.parameterQname.prefix: self.xmlns[fObj.parameterQname.prefix] = fObj.parameterQname.namespaceURI self.xf = "{}parameter {} {{".format(pIndent, fObj.parameterQname) if fObj.isRequired: self.xf = "{}required".format(cIndent) self.xf = "{} select {{{}}}".format(cIndent, fObj.select) if fObj.asType: self.xf = "{} as {{{}}}".format(cIndent, fObj.asType) if fObj.asType.prefix: self.xmlns[fObj.asType.prefix] = fObj.asType.namespaceURI self.xf = "{}}};".format(pIndent) elif isinstance(fObj, ModelFilter): if fromRel.isComplemented: self.xf = "{}complemented".format(pIndent) if not fromRel.isCovered and fromRel.localName == "variableFilterArc": self.xf = "{}non-covering".format(pIndent) if isinstance(fObj, ModelConceptName): if len(fObj.conceptQnames) == 1 and not fObj.qnameExpressions: qn = next(iter(fObj.conceptQnames)) self.xmlns[qn.prefix] = qn.namespaceURI self.xf = "{}concept-name {};".format(pIndent, qn) elif len(fObj.qnameExpressions) == 1 and not fObj.conceptQnames: self.xf = "{}concept-name {{{}}};".format(pIndent, fObj.qnameExpressions[0]) else: self.xf = "{}concept-name".format(pIndent) for qn in fObj.conceptQnames: self.xmlns[qn.prefix] = qn.namespaceURI self.xf = "{} {}".format(pIndent, qn) for qnExpr in fObj.qnameExpressions: self.xf = "{} {}".format(pIndent, qnExpr) self.xf = "{} ;".format(pIndent) elif isinstance(fObj, ModelConceptPeriodType): self.xf = "{}concept-period {};".format(pIndent, fObj.periodType) elif isinstance(fObj, ModelConceptBalance): self.xf = "{}concept-balance {};".format(pIndent, fObj.balance) elif isinstance(fObj, (ModelConceptDataType, ModelConceptSubstitutionGroup)): self.xf = "{}{} {} {};".format(pIndent, kebabCase(fObj.localName), "strict" if fObj.strict == "true" else "non-strict", fObj.filterQname if fObj.filterQname else "{{{}}}".format(fObj.qnameExpression)) elif isinstance(fObj, ModelExplicitDimension): members = [] for memberElt in XmlUtil.children(fObj, XbrlConst.df, "member"): members.append("member") member = XmlUtil.childText(memberElt, XbrlConst.df, "qname") if member: member = str(member) # qname, must coerce to string else: member = XmlUtil.childText(memberElt, XbrlConst.df, "qnameExpression") if member: member = "{{{}}}".format(member) else: member = "$" + XmlUtil.childText(memberElt, XbrlConst.df, "variable") members.append(member) linkrole = XmlUtil.childText(memberElt, XbrlConst.df, "linkrole") if linkrole: members.append("linkrole") members.append("\"{}\"".format(linkrole)) arcrole = XmlUtil.childText(memberElt, XbrlConst.df, "arcrole") if arcrole: members.append("arcrole") members.append("\"{}\"".format(arcrole)) axis = XmlUtil.childText(memberElt, XbrlConst.df, "axis") if axis: members.append("axis") members.append(axis) self.xf = "{}explicit-dimension {}{};".format(pIndent, fObj.dimQname or ("{{{}}}".format(fObj.dimQnameExpression) if fObj.dimQnameExpression else ""), " ".join(members)) elif isinstance(fObj, ModelTypedDimension): # this is a ModelTestFilter not same as genera/unit/period self.xf = "{}typed-dimension {}{};".format(pIndent, fObj.dimQname or ("{{{}}}".format(fObj.dimQnameExpression) if fObj.dimQnameExpression else ""), " {{{}}}".format(fObj.test) if fObj.test else "") elif isinstance(fObj, ModelTestFilter): self.xf = "{}{} {{{}}};".format(pIndent, "general" if isinstance(fObj, ModelGeneral) else "unit-general-measures" if isinstance(fObj, ModelGeneralMeasures) else "period" if isinstance(fObj, ModelPeriod) else "entity-identifier" if isinstance(fObj, ModelIdentifier) else None, fObj.test) elif isinstance(fObj, ModelDateTimeFilter): self.xf = "{}{} {{{}}}{};".format(pIndent, kebabCase(fObj.localName), fObj.date, " {{{}}}".format(fObj.time) if fObj.time else "") elif isinstance(fObj, ModelInstantDuration): self.xf = "{}instant-duration {} {};".format(pIndent, fObj.boundary, fObj.variable) elif isinstance(fObj, ModelSingleMeasure): self.xf = "{}unit-single-measure {};".format(pIndent, fObj.measureQname or ("{{{}}}".format(fObj.qnameExpression) if fObj.qnameExpression else "")) elif isinstance(fObj, ModelEntitySpecificIdentifier): self.xf = "{}entity scheme {{{}}} value {{{}}};".format(pIndent, fObj.scheme, fObj.value) elif isinstance(fObj, ModelEntityScheme): self.xf = "{}entity-scheme {{{}}};".format(pIndent, fObj.scheme) elif isinstance(fObj, ModelEntityRegexpScheme): self.xf = "{}entity-scheme-pattern \"{}\";".format(pIndent, fObj.pattern) elif isinstance(fObj, ModelEntityRegexpIdentifier): self.xf = "{}entity-identifier-pattern \"{}\";".format(pIndent, fObj.pattern) elif isinstance(fObj, ModelMatchFilter): self.xf = "{}{} ${} {}{};".format(pIndent, kebabCase(fObj.localName), fObj.variable, " dimension {}".format(fObj.dimension) if fObj.get("dimension") else "", " match-any" if fObj.matchAny else "") elif isinstance(fObj, ModelRelativeFilter): self.xf = "{}relative ${};".format(pIndent, fObj.variable) elif isinstance(fObj, ModelAncestorFilter): self.xf = "{}ancestor {};".format(pIndent, fObj.ancestorQname or ("{{{}}}".format(fObj.qnameExpression) if fObj.qnameExpression else "")) elif isinstance(fObj, ModelParentFilter): self.xf = "{}parent {};".format(pIndent, fObj.parentQname or ("{{{}}}".format(fObj.qnameExpression) if fObj.qnameExpression else "")) elif isinstance(fObj, ModelSiblingFilter): self.xf = "{}sibling ${};".format(pIndent, fObj.variable) elif isinstance(fObj, ModelNilFilter): self.xf = "{}nilled;".format(pIndent) elif isinstance(fObj, ModelAspectCover): aspects = [] for aspectElt in XmlUtil.children(fObj, XbrlConst.acf, "aspect"): aspects.append(XmlUtil.text(aspectElt)) for dimElt in XmlUtil.descendants(fObj, XbrlConst.acf, ("qname", "qnameExpression")): dimAspect = qname( dimElt, XmlUtil.text(dimElt) ) aspects.append("exclude-dimension" if dimElt.getparent().localName == "excludeDimension" else "dimension") if dimElt.localName == "qname": aspects.append(str(qname( dimElt, XmlUtil.text(dimElt) ))) else: aspects.append("{{{}}}".format(XmlUtil.text(dimElt))) self.xf = "{}aspect-cover {};".format(pIndent, " ".join(aspects)) elif isinstance(fObj, ModelConceptRelation): conceptRelationTerms = [] if fObj.sourceQname: conceptRelationTerms.append(fObj.sourceQname) elif fObj.variable: conceptRelationTerms.append("$" + fObj.variable) else: conceptRelationTerms.append("{{{}}}".format(fObj.sourceQnameExpression)) if fObj.linkrole: conceptRelationTerms.append("linkrole") conceptRelationTerms.append(fObj.linkrole) elif fObj.linkroleExpression: conceptRelationTerms.append("linkrole") conceptRelationTerms.append("{{{}}}".format(fObj.linkroleExpression)) if fObj.arcrole: conceptRelationTerms.append("arcrole") conceptRelationTerms.append(fObj.arcrole) elif fObj.arcroleExpression: conceptRelationTerms.append("arcrole") conceptRelationTerms.append("{{{}}}".format(fObj.arcroleExpression)) if fObj.axis: conceptRelationTerms.append("axis") conceptRelationTerms.append(fObj.axis) if fObj.generations is not None: conceptRelationTerms.append("generations {}".format(fObj.generations)) if fObj.test: conceptRelationTerms.append("test") conceptRelationTerms.append("{{{}}}".format(fObj.test)) self.xf = "{}concept-relation {};".format(pIndent, " ".join(conceptRelationTerms)) elif isinstance(fObj, (ModelAndFilter, ModelOrFilter)): self.xf = "{}{} {{".format(pIndent, "and" if isinstance(fObj, ModelAndFilter)else "or") if fObj not in visited: visited.add(fObj) for modelRel in self.modelXbrl.relationshipSet(XbrlConst.booleanFilter).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, cIndent, visited) visited.remove(fObj) self.xf = "{}}};".format(pIndent) elif isinstance(fObj, ModelMessage): self.xf = "{}{}{} \"{}\";".format( pIndent, "satisfied-message" if fromRel.arcrole == XbrlConst.assertionSatisfiedMessage else "unsatisfied-message", " ({})".format(fObj.xmlLang) if fObj.xmlLang else "", fObj.text.replace('"', '""')) elif isinstance(fObj, ModelCustomFunctionSignature): hasImplememntation = False if fObj not in visited: visited.add(fObj) for modelRel in self.modelXbrl.relationshipSet(XbrlConst.functionImplementation).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, pIndent, visited) # note: use pIndent as parent doesn't show hasImplementation = True visited.remove(fObj) if not hasImplementation: self.xmlns[fObj.functionQname.prefix] = fObj.functionQname.namespaceURI self.xf = "{}abstract-function {}({}) as {};".format(pIndent, fObj.name, ", ".join(str(t) for t in fObj.inputTypes), fObj.outputType) elif isinstance(fObj, ModelCustomFunctionImplementation): sigObj = fromRel.fromModelObject self.xmlns[sigObj.functionQname.prefix] = sigObj.functionQname.namespaceURI self.xf = "{}function {}({}) as {} {{".format(pIndent, sigObj.name, ", ".join("{} as {}".format(inputName, sigObj.inputTypes[i]) for i, inputName in enumerate(fObj.inputNames)), sigObj.outputType) for name, stepExpr in fObj.stepExpressions: if "\n" not in stepExpr: self.xf = "{}step ${} {{{}}};".format(cIndent, name, stepExpr) else: self.xf = "{}step ${} {{".format(cIndent, name) for exprLine in stepExpr.split("\n"): self.xf = "{} {}".format(cIndent, exprLine.lstrip()) self.xf = "{}}};".format(cIndent) self.xf = "{}return {{{}}};".format(cIndent, fObj.outputExpression) self.xf = "{}}};".format(pIndent) elif fObj.getparent().tag == "{http://xbrl.org/2008/formula}aspects": # aspect rules arg = "" if fObj.localName == "concept": if XmlUtil.hasChild(fObj, None, "qname"): arg += " " + XmlUtil.childText(fObj, None, "qname") elif XmlUtil.hasChild(fObj, None, "qnameExpression"): arg += " {" + XmlUtil.childText(fObj, None, "qnameExpression") + "}" elif fObj.localName == "entityIdentifier": if fObj.get("scheme"): arg += " scheme {" + fObj.get("scheme") + "}" if fObj.get("identifier"): arg += " identifier {" + fObj.get("identifier") + "}" elif fObj.localName == "period": if XmlUtil.hasChild(fObj, None, "forever"): arg += " forever" if XmlUtil.hasChild(fObj, None, "instant"): arg += " instant" attr = XmlUtil.childAttr(fObj, None, "instant", "value") if attr: arg += "{" + attr + "}" if XmlUtil.hasChild(fObj, None, "duration"): arg += " duration" attr = XmlUtil.childAttr(fObj, None, "duration", "start") if attr: arg += " start {" + attr + "}" attr = XmlUtil.childAttr(fObj, None, "duration", "end") if attr: arg += " end {" + attr + "}" elif fObj.localName == "unit": if fObj.get("augment") == "true": arg += " augment" if fObj.localName in ("explicitDimension", "typedDimension"): arg += " dimension " + fObj.get("dimension") if fObj.localName in ("concept", "entityIdentifier", "period"): arg += ";" else: arg += " {" self.xf = "{}{}{}".format(pIndent, kebabCase(fObj.localName), arg) if fObj.localName == "unit": for elt in fObj.iterchildren(): arg = "" if elt.get("source"): arg += " source " + elt.get("source") if elt.get("measure"): arg += " measure {" + elt.get("measure") + "}" self.xf = "{}{}{};".format(cIndent, kebabCase(elt.localName), arg) elif fObj.localName == "explicitDimension": for elt in fObj.iterchildren(): arg = "" if XmlUtil.hasChild(elt, None, "qname"): arg += " " + XmlUtil.childText(elt, None, "qname") elif XmlUtil.hasChild(elt, None, "qnameExpression"): arg += " {" + XmlUtil.childText(elt, None, "qnameExpression") + "}" self.xf = "{}{}{};".format(cIndent, kebabCase(elt.localName), arg) elif fObj.localName == "typedDimension": for elt in fObj.iterchildren(): arg = "" if XmlUtil.hasChild(elt, None, "xpath"): arg += " xpath {" + ModelXbrl.childText(elt, None, "xpath") + "}" elif XmlUtil.hasChild(elt, None, "value"): arg += " value " + strQoute(XmlUtil.xmlstring(XmlUtil.child(elt, None, "value"), stripXmlns=True, contentsOnly=False)) self.xf = "{}{}{};".format(cIndent, kebabCase(elt.localName), arg) if fObj.localName not in ("concept", "entityIdentifier", "period"): self.xf = "{}}};".format(pIndent) # check for prefixes in AST of programs of fObj if hasattr(fObj, "compile") and type(fObj.compile).__name__ == "method": fObj.compile() for _prog, _ast in fObj.__dict__.items(): if _prog.endswith("Prog") and isinstance(_ast, list): XPathParser.prefixDeclarations(_ast, self.xmlns, fObj)
def propertyView(self): if self.isExplicit: return (str(self.dimensionQname),str(self.memberQname)) else: return (str(self.dimensionQname), XmlUtil.xmlstring( XmlUtil.child(self), stripXmlns=True, prettyPrint=True ) )
def viewConcept(self, concept, modelObject, labelPrefix, preferredLabel, indent, arcrole, relationshipSet, visited): try: if concept is None: return isRelation = isinstance(modelObject, ModelRelationship) childRelationshipSet = relationshipSet if isinstance(concept, ModelDtsObject.ModelConcept): text = labelPrefix + concept.label(preferredLabel,lang=self.lang,linkroleHint=relationshipSet.linkrole) if (self.arcrole in ("XBRL-dimensions", XbrlConst.hypercubeDimension) and concept.isTypedDimension and concept.typedDomainElement is not None): text += " (typedDomain={0})".format(concept.typedDomainElement.qname) xmlRowElementName = "concept" attr = {"name": str(concept.qname)} elif self.arcrole == "Table-rendering": text = concept.localName xmlRowElementName = "element" attr = {"label": concept.xlinkLabel} elif isinstance(concept, ModelDtsObject.ModelResource): if self.showReferences: text = (concept.viewText().strip() or concept.localName) attr = {"text": text, "innerXml": XmlUtil.xmlstring(concept, stripXmlns=True, prettyPrint=False, contentsOnly=True)} else: text = (concept.elementText.strip() or concept.localName) attr = {"text": text} xmlRowElementName = "resource" else: # just a resource text = concept.localName xmlRowElementName = text cols = [text] if arcrole == "XBRL-dimensions" and isRelation: relArcrole = modelObject.arcrole cols.append( os.path.basename( relArcrole ) ) if relArcrole in (XbrlConst.all, XbrlConst.notAll): cols.append( modelObject.contextElement ) cols.append( modelObject.closed ) else: cols.append(None) cols.append(None) if relArcrole in (XbrlConst.dimensionDomain, XbrlConst.domainMember): cols.append( modelObject.usable ) childRelationshipSet = self.modelXbrl.relationshipSet(XbrlConst.consecutiveArcrole.get(relArcrole,"XBRL-dimensions"), modelObject.linkrole) if self.arcrole == XbrlConst.parentChild: # extra columns if isRelation: preferredLabel = modelObject.preferredLabel if preferredLabel.startswith("http://www.xbrl.org/2003/role/"): preferredLabel = os.path.basename(preferredLabel) else: preferredLabel = None cols.append(preferredLabel) cols.append(concept.niceType) cols.append(viewReferences(concept)) elif arcrole == XbrlConst.summationItem: if isRelation: cols.append("{:0g} ".format(modelObject.weight)) else: cols.append("") # no weight on roots cols.append(concept.balance) elif self.isResourceArcrole: # resource columns if isRelation: cols.append(modelObject.arcrole) else: cols.append("") # no weight on roots if isinstance(concept, ModelDtsObject.ModelResource): cols.append(concept.localName) cols.append(concept.role or '') cols.append(concept.xmlLang) self.addRow(cols, treeIndent=indent, xmlRowElementName=xmlRowElementName, xmlRowEltAttr=attr, xmlCol0skipElt=True) if concept not in visited: visited.add(concept) for modelRel in childRelationshipSet.fromModelObject(concept): nestedRelationshipSet = relationshipSet targetRole = modelRel.targetRole if arcrole == XbrlConst.summationItem: childPrefix = "({:+0g}) ".format(modelRel.weight) # format without .0 on integer weights elif targetRole is None or len(targetRole) == 0: targetRole = relationshipSet.linkrole childPrefix = "" else: nestedRelationshipSet = self.modelXbrl.relationshipSet(childRelationshipSet.arcrole, targetRole) childPrefix = "(via targetRole) " toConcept = modelRel.toModelObject if toConcept in visited: childPrefix += "(loop) " self.viewConcept(toConcept, modelRel, childPrefix, (modelRel.preferredLabel or self.labelrole), indent + 1, arcrole, nestedRelationshipSet, visited) visited.remove(concept) except AttributeError: # bad relationship return
def viewConcept(self, concept, modelObject, labelPrefix, preferredLabel, indent, arcrole, relationshipSet, visited): try: if concept is None: return isRelation = isinstance(modelObject, ModelRelationship) childRelationshipSet = relationshipSet if isinstance(concept, ModelDtsObject.ModelConcept): text = labelPrefix + concept.label(preferredLabel,lang=self.lang,linkroleHint=relationshipSet.linkrole) if (self.arcrole in ("XBRL-dimensions", XbrlConst.hypercubeDimension) and concept.isTypedDimension and concept.typedDomainElement is not None): text += " (typedDomain={0})".format(concept.typedDomainElement.qname) xmlRowElementName = "concept" #[email protected]: 15-Feb-2017 - start # added "id", "name", "abstract", "substitutionGroup", # "dataType", "nillable", "perioType", "balanceType" and "preferredLabel" so that can be imported to database namespace = "" if (str(concept.id) is not None): splitted = str(concept.id).split("_") if (len(splitted) > 1): namespace = splitted[0] attr = { "namespace": namespace, "name": str(concept.name), "abstract": str(concept.abstract), "substitutionGroup": str(concept.substitutionGroupQname), "dataType": str(concept.typeQname), "nillable": str(concept.nillable), "periodType": str(concept.periodType), "balanceType": str(concept.balance)} if preferredLabel != XbrlConst.conceptNameLabelRole and concept.label != None: attr["standardLabel"] = str(concept.label(XbrlConst.standardLabel,lang=self.lang,linkroleHint=relationshipSet.linkrole)) if preferredLabel != None: attr["preferredLabel"] = os.path.basename(preferredLabel) if preferredLabel == XbrlConst.periodStartLabel and concept.label != None: attr["periodStartLabel"] = str(concept.label(XbrlConst.periodStartLabel,lang=self.lang,linkroleHint=relationshipSet.linkrole)) if preferredLabel == XbrlConst.periodEndLabel and concept.label != None: attr["periodEndLabel"] = str(concept.label(XbrlConst.periodEndLabel,lang=self.lang,linkroleHint=relationshipSet.linkrole)) if preferredLabel != None and os.path.basename(preferredLabel) == "totalLabel": attr["totalLabel"] = text if concept.label != None: attr["documentation"] = str(concept.label(XbrlConst.documentationLabel,lang=self.lang,linkroleHint=relationshipSet.linkrole)) if viewReferences(concept) != None and len(viewReferences(concept)) > 0: attr["references"] = viewReferences(concept) #[email protected]: 15-Feb-2017 - end elif self.arcrole == "Table-rendering": text = concept.localName xmlRowElementName = "element" attr = {"label": concept.xlinkLabel} elif isinstance(concept, ModelDtsObject.ModelResource): if self.showReferences: text = (concept.viewText().strip() or concept.localName) attr = {"text": text, "innerXml": XmlUtil.xmlstring(concept, stripXmlns=True, prettyPrint=False, contentsOnly=True)} else: text = (concept.textValue.strip() or concept.localName) attr = {"text": text} xmlRowElementName = "resource" else: # just a resource text = concept.localName xmlRowElementName = text #[email protected]: 15-Feb-2017 cols = [text, str(concept.name), str(concept.typeQname)] if arcrole == "XBRL-dimensions" and isRelation: relArcrole = modelObject.arcrole cols.append( os.path.basename( relArcrole ) ) if relArcrole in (XbrlConst.all, XbrlConst.notAll): cols.append( modelObject.contextElement ) cols.append( modelObject.closed ) else: cols.append(None) cols.append(None) if relArcrole in (XbrlConst.dimensionDomain, XbrlConst.domainMember): cols.append( modelObject.usable ) childRelationshipSet = self.modelXbrl.relationshipSet(XbrlConst.consecutiveArcrole.get(relArcrole,"XBRL-dimensions"), modelObject.consecutiveLinkrole) if self.arcrole == XbrlConst.parentChild: # extra columns if isRelation: preferredLabel = modelObject.preferredLabel if preferredLabel and preferredLabel.startswith("http://"): preferredLabel = os.path.basename(preferredLabel) else: preferredLabel = None #[email protected]: 15-Feb-2017 commented below 2 lines to avoid loading preferredLabel & type again #cols.append(preferredLabel) #cols.append(concept.niceType) #cols.append(viewReferences(concept)) elif arcrole == XbrlConst.summationItem: if isRelation: cols.append("{:0g} ".format(modelObject.weight)) else: cols.append("") # no weight on roots cols.append(concept.balance) elif self.isResourceArcrole: # resource columns if isRelation: cols.append(modelObject.arcrole) else: cols.append("") # no weight on roots if isinstance(concept, ModelDtsObject.ModelResource): cols.append(concept.localName) cols.append(concept.role or '') cols.append(concept.xmlLang) #[email protected]: 31-Jul-2018 - remove extra columns del cols[1:3] self.addRow(cols, treeIndent=indent, xmlRowElementName=xmlRowElementName, xmlRowEltAttr=attr, xmlCol0skipElt=True) if concept not in visited: visited.add(concept) for modelRel in childRelationshipSet.fromModelObject(concept): nestedRelationshipSet = relationshipSet targetRole = modelRel.targetRole if arcrole == XbrlConst.summationItem: childPrefix = "({:+0g}) ".format(modelRel.weight) # format without .0 on integer weights elif targetRole is None or len(targetRole) == 0: targetRole = relationshipSet.linkrole childPrefix = "" else: nestedRelationshipSet = self.modelXbrl.relationshipSet(childRelationshipSet.arcrole, targetRole) childPrefix = "(via targetRole) " toConcept = modelRel.toModelObject if toConcept in visited: childPrefix += "(loop) " labelrole = modelRel.preferredLabel if not labelrole or self.labelrole == conceptNameLabelRole: labelrole = self.labelrole self.viewConcept(toConcept, modelRel, childPrefix, labelrole, indent + 1, arcrole, nestedRelationshipSet, visited) visited.remove(concept) except AttributeError: # bad relationship return
def viewConcept(self, concept, modelObject, labelPrefix, preferredLabel, indent, arcrole, relationshipSet, visited): try: if concept is None: return isRelation = isinstance(modelObject, ModelRelationship) childRelationshipSet = relationshipSet if isinstance(concept, ModelDtsObject.ModelConcept): text = labelPrefix + concept.label( preferredLabel, lang=self.lang, linkroleHint=relationshipSet.linkrole) if (self.arcrole in ("XBRL-dimensions", XbrlConst.hypercubeDimension) and concept.isTypedDimension and concept.typedDomainElement is not None): text += " (typedDomain={0})".format( concept.typedDomainElement.qname) xmlRowElementName = "concept" attr = {"name": str(concept.qname)} if preferredLabel != XbrlConst.conceptNameLabelRole: attr["label"] = text elif self.arcrole == "Table-rendering": text = concept.localName xmlRowElementName = "element" attr = {"label": concept.xlinkLabel} elif isinstance(concept, ModelDtsObject.ModelResource): if self.showReferences: text = (concept.viewText().strip() or concept.localName) attr = { "text": text, "innerXml": XmlUtil.xmlstring(concept, stripXmlns=True, prettyPrint=False, contentsOnly=True) } else: text = (concept.textValue.strip() or concept.localName) attr = {"text": text} xmlRowElementName = "resource" else: # just a resource text = concept.localName xmlRowElementName = text cols = [text] if arcrole == "XBRL-dimensions" and isRelation: relArcrole = modelObject.arcrole cols.append(os.path.basename(relArcrole)) if relArcrole in (XbrlConst.all, XbrlConst.notAll): cols.append(modelObject.contextElement) cols.append(modelObject.closed) else: cols.append(None) cols.append(None) if relArcrole in (XbrlConst.dimensionDomain, XbrlConst.domainMember): cols.append(modelObject.usable) childRelationshipSet = self.modelXbrl.relationshipSet( XbrlConst.consecutiveArcrole.get(relArcrole, "XBRL-dimensions"), modelObject.consecutiveLinkrole) if self.arcrole == XbrlConst.parentChild: # extra columns if isRelation: preferredLabel = modelObject.preferredLabel if preferredLabel and preferredLabel.startswith("http://"): preferredLabel = os.path.basename(preferredLabel) else: preferredLabel = None cols.append(preferredLabel) cols.append(concept.niceType) cols.append(viewReferences(concept)) elif arcrole == XbrlConst.summationItem: if isRelation: cols.append("{:0g} ".format(modelObject.weight)) else: cols.append("") # no weight on roots cols.append(concept.balance) elif self.isResourceArcrole: # resource columns if isRelation: cols.append(modelObject.arcrole) else: cols.append("") # no weight on roots if isinstance(concept, ModelDtsObject.ModelResource): cols.append(concept.localName) cols.append(concept.role or '') cols.append(concept.xmlLang) elif self.arcrole == "Table-rendering": try: header = concept.header(lang=self.lang, strip=True, evaluate=False) except AttributeError: header = None # could be a filter if isRelation: cols.append(modelObject.axisDisposition) else: cols.append('') if isRelation and header is None: header = "{0} {1}".format( os.path.basename(modelObject.arcrole), concept.xlinkLabel) if concept.get("abstract") == "true": cols.append('\u2713') else: cols.append('') if concept.get("merge") == "true": cols.append('\u2713') else: cols.append('') cols.append(header) if isRelation and isinstance( concept, (ModelEuAxisCoord, ModelRuleDefinitionNode)): cols.append(concept.aspectValue(None, Aspect.CONCEPT)) if self.type in (CSV, XML, JSON): # separate dimension fields for dim in (concept.aspectValue( None, Aspect.DIMENSIONS, inherit=False) or ()): cols.append(dim) cols.append(concept.aspectValue(None, dim)) else: # combined dimension fields cols.append(' '.join( ("{0},{1}".format(dim, concept.aspectValue(None, dim)) for dim in (concept.aspectValue( None, Aspect.DIMENSIONS, inherit=False) or ()) ))) else: cols.append('') elif self.arcrole == widerNarrower: if isRelation: otherWider = [ modelRel.fromModelObject for modelRel in childRelationshipSet.toModelObject( concept) if modelRel.fromModelObject != modelObject.fromModelObject ] cols.append(", ".join( w.label(preferredLabel, lang=self.lang, linkroleHint=relationshipSet.linkrole, fallbackToQname=False) for w in otherWider)) else: cols.append("") if self.cols and len(self.cols) > 1: for col in self.cols: if col == "Name": cols.append((concept.qname or concept.prefixedName)) elif col == "Documentation": cols.append( concept.label( documentationLabel, lang=self.lang, linkroleHint=relationshipSet.linkrole)) elif col == "References": cols.append(viewReferences(concept)) self.addRow(cols, treeIndent=indent, xmlRowElementName=xmlRowElementName, xmlRowEltAttr=attr, xmlCol0skipElt=True, arcRole=self.arcrole) if concept not in visited: visited.add(concept) for modelRel in childRelationshipSet.fromModelObject(concept): nestedRelationshipSet = relationshipSet targetRole = modelRel.targetRole if arcrole == XbrlConst.summationItem: childPrefix = "({:+0g}) ".format( modelRel.weight ) # format without .0 on integer weights elif targetRole is None or len(targetRole) == 0: targetRole = relationshipSet.linkrole childPrefix = "" else: nestedRelationshipSet = self.modelXbrl.relationshipSet( childRelationshipSet.arcrole, targetRole) childPrefix = "(via targetRole) " toConcept = modelRel.toModelObject if toConcept in visited: childPrefix += "(loop) " labelrole = modelRel.preferredLabel if not labelrole or self.labelrole == conceptNameLabelRole: labelrole = self.labelrole self.viewConcept(toConcept, modelRel, childPrefix, labelrole, indent + 1, arcrole, nestedRelationshipSet, visited) visited.remove(concept) except AttributeError: # bad relationship return
def doObject(self, fObj, fromRel, pIndent, visited): if fObj is None: return cIndent = pIndent + " " if isinstance(fObj, (ModelValueAssertion, ModelExistenceAssertion, ModelFormula)): varSetType = "formula" if isinstance(fObj, ModelFormula) else "assertion" eltNbr = self.eltTypeCount[varSetType] = self.eltTypeCount.get(varSetType, 0) + 1 _id = fObj.id or "{}{}".format(varSetType, eltNbr) self.xf = "{}{} {} {{".format(pIndent, varSetType, _id) for arcrole in (XbrlConst.elementLabel, XbrlConst.assertionSatisfiedMessage, XbrlConst.assertionUnsatisfiedMessage): for modelRel in self.modelXbrl.relationshipSet(arcrole).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, cIndent, visited) if fObj.aspectModel == "non-dimensional": self.xf = "{}aspect-model-non-dimensional;".format(cIndent) if fObj.implicitFiltering == "false": self.xf = "{}no-implicit-filtering;".format(cIndent) if isinstance(fObj, ModelFormula): for attr in ("decimals", "precision", "value"): if fObj.get(attr): self.xf = "{}{} {{{}}};".format(cIndent, attr, fObj.get(attr)) if fObj.get("source"): self.xf = "{}source {};".format(cIndent, fObj.get("source")) for aspectsElt in XmlUtil.children(fObj, XbrlConst.formula, "aspects"): self.xf = "{}aspect-rules{} {{".format(cIndent, "source {}".format(aspectsElt.get("source")) if aspectsElt.get("source") else "") for ruleElt in XmlUtil.children(aspectsElt, XbrlConst.formula, "*"): self.doObject(ruleElt, None, cIndent + " ", visited) self.xf = "{}}};".format(cIndent) for arcrole in (XbrlConst.variableSetFilter, XbrlConst.variableSet, XbrlConst.variableSetPrecondition): for modelRel in self.modelXbrl.relationshipSet(arcrole).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, cIndent, visited) if isinstance(fObj, ModelValueAssertion): self.xf = "{}test {{{}}}".format(cIndent, fObj.viewExpression) elif isinstance(fObj, ModelExistenceAssertion): self.xf = "{}evaluation-count {{{}}}".format(cIndent, fObj.viewExpression or ". gt 0") self.xf = "{}}};".format(pIndent) elif isinstance(fObj, ModelConsistencyAssertion): eltNbr = self.eltTypeCount["consistencyAssertion"] = self.eltTypeCount.get("consistencyAssertion", 0) + 1 _id = fObj.id or "{}{}".format("consistencyAssertion", eltNbr) self.xf = "{}consistency-assertion {} {{".format(pIndent, _id) for arcrole in (XbrlConst.elementLabel, XbrlConst.assertionSatisfiedMessage, XbrlConst.assertionUnsatisfiedMessage): for modelRel in self.modelXbrl.relationshipSet(arcrole).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, cIndent, visited) if fObj.isStrict: self.xf = "{}strict;".format(cIndent) if fObj.get("proportionalAcceptanceRadius"): self.xf = "{}proportional-acceptance-radius {{{}}};".format(cIndent, fObj.get("proportionalAcceptanceRadius")) if fObj.get("absoluteAcceptanceRadius"): self.xf = "{}absolute-acceptance-radius {{{}}};".format(cIndent, fObj.get("absoluteAcceptanceRadius")) for modelRel in self.modelXbrl.relationshipSet(XbrlConst.consistencyAssertionFormula).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, cIndent, visited) self.xf = "{}}};".format(pIndent) elif isinstance(fObj, ModelFactVariable) and fromRel is not None: self.xf = "{}variable ${} {{".format(pIndent, fromRel.variableQname) if fromRel.variableQname.prefix: self.xmlns[fromRel.variableQname.prefix] = fromRel.variableQname.namespaceURI if fObj.bindAsSequence == "true": self.xf = "{}bind-as-sequence".format(cIndent) if fObj.nils == "true": self.xf = "{}nils".format(cIndent) if fObj.matches == "true": self.xf = "{}matches".format(cIndent) if fObj.fallbackValue: self.xf = "{}fallback {{{}}}".format(cIndent, fObj.fallbackValue) for modelRel in self.modelXbrl.relationshipSet(XbrlConst.variableFilter).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, cIndent, visited) self.xf = "{}}};".format(pIndent) elif isinstance(fObj, ModelGeneralVariable) and fromRel is not None: self.xf = "{}variable ${} {{".format(pIndent, fromRel.variableQname) if fromRel.variableQname.prefix: self.xmlns[fromRel.variableQname.prefix] = fromRel.variableQname.namespaceURI if fObj.bindAsSequence: self.xf = "{}bind-as-sequence".format(cIndent) self.xf = "{}select {{{}}}".format(cIndent, fObj.select) elif isinstance(fObj, ModelParameter): if fromRel is not None: # parameter is referenced by a different QName on arc if fromRel.variableQname.prefix: self.xmlns[fromRel.variableQname.prefix] = fromRel.variableQname.namespaceURI self.xf = "{}parameter ${} references ${};".format(pIndent, fromRel.variableQname, fObj.parameterQname) else: # root level parameter if fObj.parameterQname.prefix: self.xmlns[fObj.parameterQname.prefix] = fObj.parameterQname.namespaceURI self.xf = "{}parameter {} {{".format(pIndent, fObj.parameterQname) if fObj.isRequired: self.xf = "{}required".format(cIndent) self.xf = "{} select {{{}}}".format(cIndent, fObj.select) if fObj.asType: self.xf = "{} as {{{}}}".format(cIndent, fObj.asType) if fObj.asType.prefix: self.xmlns[fObj.asType.prefix] = fObj.asType.namespaceURI self.xf = "{}}};".format(pIndent) elif isinstance(fObj, ModelFilter): if fromRel.isComplemented: self.xf = "{}complemented".format(pIndent) if not fromRel.isCovered and fromRel.localName == "variableFilterArc": self.xf = "{}non-covering".format(pIndent) if isinstance(fObj, ModelConceptName): if len(fObj.conceptQnames) == 1 and not fObj.qnameExpressions: qn = next(iter(fObj.conceptQnames)) self.xmlns[qn.prefix] = qn.namespaceURI self.xf = "{}concept-name {};".format(pIndent, qn) elif len(fObj.qnameExpressions) == 1 and not fObj.conceptQnames: self.xf = "{}concept-name {{{}}};".format(pIndent, fObj.qnameExpressions[0]) else: self.xf = "{}concept-name".format(pIndent) for qn in fObj.conceptQnames: self.xmlns[qn.prefix] = qn.namespaceURI self.xf = "{} {}".format(pIndent, qn) for qnExpr in fObj.qnameExpressions: self.xf = "{} {}".format(pIndent, qnExpr) self.xf = "{} ;".format(pIndent) elif isinstance(fObj, ModelConceptPeriodType): self.xf = "{}concept-period {};".format(pIndent, fObj.periodType) elif isinstance(fObj, ModelConceptBalance): self.xf = "{}concept-balance {};".format(pIndent, fObj.balance) elif isinstance(fObj, (ModelConceptDataType, ModelConceptSubstitutionGroup)): self.xf = "{}{} {} {};".format(pIndent, kebabCase(fObj.localName), "strict" if fObj.strict == "true" else "non-strict", fObj.filterQname if fObj.filterQname else "{{{}}}".format(fObj.qnameExpression)) elif isinstance(fObj, ModelExplicitDimension): members = [] for memberElt in XmlUtil.children(fObj, XbrlConst.df, "member"): members.append("member") member = XmlUtil.childText(memberElt, XbrlConst.df, "qname") if member: member = str(member) # qname, must coerce to string else: member = XmlUtil.childText(memberElt, XbrlConst.df, "qnameExpression") if member: member = "{{{}}}".format(member) else: member = "$" + XmlUtil.childText(memberElt, XbrlConst.df, "variable") members.append(member) linkrole = XmlUtil.childText(memberElt, XbrlConst.df, "linkrole") if linkrole: members.append("linkrole") members.append("\"{}\"".format(linkrole)) arcrole = XmlUtil.childText(memberElt, XbrlConst.df, "arcrole") if arcrole: members.append("arcrole") members.append("\"{}\"".format(arcrole)) axis = XmlUtil.childText(memberElt, XbrlConst.df, "axis") if axis: members.append("axis") members.append(axis) self.xf = "{}explicit-dimension {}{};".format(pIndent, fObj.dimQname or "{{{}}}".format(fObj.dimQnameExpression) if fObj.dimQnameExpression else "", " ".join(members)) elif isinstance(fObj, ModelTypedDimension): # this is a ModelTestFilter not same as genera/unit/period self.xf = "{}typed-dimension {}{};".format(pIndent, fObj.dimQname or "{{{}}}".format(fObj.dimQnameExpression) if fObj.dimQnameExpression else "", " {{{}}}".format(fObj.test) if fObj.test else "") elif isinstance(fObj, ModelTestFilter): self.xf = "{}{} {{{}}};".format(pIndent, "general" if isinstance(fObj, ModelGeneral) else "unit-general-measures" if isinstance(fObj, ModelGeneralMeasures) else "period" if isinstance(fObj, ModelPeriod) else "entity-identifier" if isinstance(fObj, ModelIdentifier) else None, fObj.test) elif isinstance(fObj, ModelDateTimeFilter): self.xf = "{}{} {{{}}}{};".format(pIndent, kebabCase(fObj.localName), fObj.date, " {{{}}}".format(fObj.time) if fObj.time else "") elif isinstance(fObj, ModelInstantDuration): self.xf = "{}instant-duration {} {};".format(pIndent, fObj.boundary, fObj.variable) elif isinstance(fObj, ModelSingleMeasure): self.xf = "{}unit {} {};".format(pIndent, fObj.boundary, fObj.variable) elif isinstance(fObj, ModelEntitySpecificIdentifier): self.xf = "{}entity scheme {{{}}} value {{{}}};".format(pIndent, fObj.scheme, fObj.value) elif isinstance(fObj, ModelEntityScheme): self.xf = "{}entity-scheme {{{}}};".format(pIndent, fObj.scheme) elif isinstance(fObj, ModelEntityRegexpScheme): self.xf = "{}entity-scheme-pattern \"{}\";".format(pIndent, fObj.pattern) elif isinstance(fObj, ModelEntityRegexpIdentifier): self.xf = "{}entity-identifier-pattern \"{}\";".format(pIndent, fObj.pattern) elif isinstance(fObj, ModelMatchFilter): self.xf = "{}{} ${} {}{};".format(pIndent, kebabCase(fObj.localName), fObj.variable, fObj.dimension or "", " match-any" if fObj.matchAny else "") elif isinstance(fObj, ModelRelativeFilter): self.xf = "{}relative ${};".format(pIndent, fObj.variable) elif isinstance(fObj, ModelAncestorFilter): self.xf = "{}ancestor {};".format(pIndent, fObj.ancestorQname or "{{{}}}".format(fObj.qnameExpression) if fObj.qnameExpression else "") elif isinstance(fObj, ModelParentFilter): self.xf = "{}parent {};".format(pIndent, fObj.parentQname or "{{{}}}".format(fObj.qnameExpression) if fObj.qnameExpression else "") elif isinstance(fObj, ModelSiblingFilter): self.xf = "{}sibling ${};".format(pIndent, fObj.variable) elif isinstance(fObj, ModelNilFilter): self.xf = "{}nilled;".format(pIndent) elif isinstance(fObj, ModelAspectCover): aspects = [] for aspectElt in XmlUtil.children(fObj, XbrlConst.acf, "aspect"): aspects.append(XmlUtil.text(aspectElt)) for dimElt in XmlUtil.descendants(fObj, XbrlConst.acf, ("qname", "qnameExpression")): dimAspect = qname( dimElt, XmlUtil.text(dimElt) ) aspects.append("exclude-dimension" if dimElt.getparent().localName == "excludeDimension" else "dimension") if dimElt.localName == "qname": aspects.append(str(qname( dimElt, XmlUtil.text(dimElt) ))) else: aspects.append("{{{}}}".format(XmlUtil.text(dimElt))) self.xf = "{}aspect-cover {};".format(pIndent, " ".join(aspects)) elif isinstance(fObj, ModelConceptRelation): conceptRelationTerms = [] if fObj.sourceQname: conceptRelationTerms.append(fObj.sourceQname) elif fObj.variable: conceptRelationTerms.append("$" + fObj.variable) else: conceptRelationTerms.append("{{{}}}".format(fObj.sourceQnameExpression)) if fObj.linkrole: conceptRelationTerms.append("linkrole") conceptRelationTerms.append(fObj.linkrole) elif fObj.linkroleExpression: conceptRelationTerms.append("linkrole") conceptRelationTerms.append("{{{}}}".format(fObj.linkroleExpression)) if fObj.arcrole: conceptRelationTerms.append("arcrole") conceptRelationTerms.append(fObj.arcrole) elif fObj.arcroleExpression: conceptRelationTerms.append("arcrole") conceptRelationTerms.append("{{{}}}".format(fObj.arcroleExpression)) if fObj.axis: conceptRelationTerms.append("axis") conceptRelationTerms.append(fObj.axis) if fObj.generations is not None: conceptRelationTerms.append("generations {}".format(fObj.generations)) if fObj.test: conceptRelationTerms.append("test") conceptRelationTerms.append("{{{}}}".format(fObj.test)) self.xf = "{}concept-relation {};".format(pIndent, " ".join(conceptRelationTerms)) elif isinstance(fObj, (ModelAndFilter, ModelOrFilter)): self.xf = "{}{} {{".format(pIndent, "and" if isinstance(fObj, ModelAndFilter)else "or") if fObj not in visited: visited.add(fObj) for modelRel in self.modelXbrl.relationshipSet(XbrlConst.booleanFilter).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, cIndent, visited) visited.remove(fObj) self.xf = "{}}};".format(pIndent) elif isinstance(fObj, ModelMessage): self.xf = "{}{}{} \"{}\";".format( pIndent, "satisfied-message" if fromRel.arcrole == XbrlConst.assertionSatisfiedMessage else "unsatisfied-message", " ({})".format(fObj.xmlLang) if fObj.xmlLang else "", fObj.text) elif isinstance(fObj, ModelCustomFunctionSignature): hasImplememntation = False if fObj not in visited: visited.add(fObj) for modelRel in self.modelXbrl.relationshipSet(XbrlConst.functionImplementation).fromModelObject(fObj): self.doObject(modelRel.toModelObject, modelRel, pIndent, visited) # note: use pIndent as parent doesn't show hasImplementation = True visited.remove(fObj) if not hasImplementation: self.xf = "{}abstract-function {}({}) as {};".format(pIndent, fObj.name, ", ".join(str(t) for t in fObj.inputTypes), fObj.outputType) elif isinstance(fObj, ModelCustomFunctionImplementation): sigObj = fromRel.fromModelObject self.xf = "{}function {}({}) as {} {{;".format(pIndent, sigObj.name, ", ".join("{} as {}".format(inputName, sigObj.inputTypes[i]) for i, inputName in enumerate(fObj.inputNames)), sigObj.outputType) for name, stepExpr in fObj.stepExpressions: if "\n" not in stepExpr: self.xf = "{}step ${} {{{}}};".format(cIndent, name, stepExpr) else: self.xf = "{}step ${} {{".format(cIndent, name) for exprLine in stepExpr.split("\n"): self.xf = "{} {}".format(cIndent, exprLine.lstrip()) self.xf = "{}}};".format(cIndent) self.xf = "{}return {{{}}};".format(cIndent, fObj.outputExpression) self.xf = "{}}};".format(pIndent) elif fObj.getparent().tag == "{http://xbrl.org/2008/formula}aspects": # aspect rules arg = "" if fObj.localName == "concept": if XmlUtil.hasChild(fObj, None, "qname"): arg += " " + XmlUtil.childText(fObj, None, "qname") elif XmlUtil.hasChild(fObj, None, "qnameExpression"): arg += " {" + XmlUtil.childText(fObj, None, "qnameExpression") + "}" elif fObj.localName == "entityIdentifier": if fObj.get("scheme"): arg += " scheme {" + fObj.get("scheme") + "}" if fObj.get("identifier"): arg += " identifier {" + fObj.get("identifier") + "}" elif fObj.localName == "period": if XmlUtil.hasChild(fObj, None, "forever"): arg += " forever" if XmlUtil.hasChild(fObj, None, "instant"): arg += " instant" attr = XmlUtil.childAttr(fObj, None, "instant", "value") if attr: arg += "{" + attr + "}" if XmlUtil.hasChild(fObj, None, "duration"): arg += " duration" attr = XmlUtil.childAttr(fObj, None, "duration", "start") if attr: arg += " start {" + attr + "}" attr = XmlUtil.childAttr(fObj, None, "duration", "end") if attr: arg += " end {" + attr + "}" elif fObj.localName == "unit": if fObj.get("augment") == "true": arg += " augment" if fObj.localName in ("explicitDimension", "typedDimension"): arg += " dimension " + fObj.get("dimension") if fObj.localName in ("concept", "entityIdentifier", "period"): arg += ";" else: arg += " {" self.xf = "{}{}{}".format(pIndent, kebabCase(fObj.localName), arg) if fObj.localName == "unit": for elt in fObj.iterchildren(): arg = "" if elt.get("source"): arg += " source " + elt.get("source") if elt.get("measure"): arg += " measure {" + elt.get("measure") + "}" self.xf = "{}{}{};".format(cIndent, kebabCase(elt.localName), arg) elif fObj.localName == "explicitDimension": for elt in fObj.iterchildren(): arg = "" if XmlUtil.hasChild(elt, None, "qname"): arg += " " + XmlUtil.childText(elt, None, "qname") elif XmlUtil.hasChild(elt, None, "qnameExpression"): arg += " {" + XmlUtil.childText(elt, None, "qnameExpression") + "}" self.xf = "{}{}{};".format(cIndent, kebabCase(elt.localName), arg) elif fObj.localName == "typedDimension": for elt in fObj.iterchildren(): arg = "" if XmlUtil.hasChild(elt, None, "xpath"): arg += " xpath {" + ModelXbrl.childText(elt, None, "xpath") + "}" elif XmlUtil.hasChild(elt, None, "value"): arg += " value " + strQoute(XmlUtil.xmlstring(XmlUtil.child(elt, None, "value"), stripXmlns=True, contentsOnly=False)) self.xf = "{}{}{};".format(cIndent, kebabCase(elt.localName), arg) if fObj.localName not in ("concept", "entityIdentifier", "period"): self.xf = "{}}};".format(pIndent)
def setArgForFactProperty(param, modelFact, propertyNameParts): propVal = None property = propertyNameParts[0] if property == "value": if isinstance(modelFact.xValue, Decimal): propVal = "{:,}".format(modelFact.xValue) else: propVal = modelFact.value elif property == "decimals": propVal = modelFact.decimals elif property == "label" and modelFact.concept is not None: propVal = modelFact.concept.label(labelrole, lang=lang, linkroleHint=XbrlConst.defaultLinkRole) elif property == "name": propVal = str(modelFact.qname) elif property == "localName": propVal = modelFact.qname.localName else: cntx = modelFact.context unit = modelFact.unit if cntx is not None: if property == "period": if len(propertyNameParts) == 1: if cntx.isForeverPeriod: propVal = "forever" elif cntx.isInstantPeriod: propVal = XmlUtil.dateunionValue(cntx.instantDatetime, subtractOneDay=True) else: propVal = "{} to {}".format(XmlUtil.dateunionValue(cntx.startDatetime), XmlUtil.dateunionValue(cntx.endDatetime, subtractOneDay=True)) else: dateSelection = propertyNameParts[1] if dateSelection == "startDate": propVal = XmlUtil.dateunionValue(cntx.startDatetime) elif dateSelection == "endDate": propVal = XmlUtil.dateunionValue(cntx.endDatetime, subtractOneDay=True) elif dateSelection == "instant": propVal = XmlUtil.dateunionValue(cntx.instant, subtractOneDay=True) elif dateSelection == "durationDays": propVal = str((cntx.endDatetime - cntx.startDatetime).days) elif property == "dimensions": if cntx.qnameDims: propVal = "\n".join("{} = {}".format(d.dimensionQname, d.memberQname if d.isExplicit else XmlUtil.xmlstring( XmlUtil.child(d), stripXmlns=True, prettyPrint=True )) for d in cntx.qnameDims.values()) else: propVal = "none" if property == "unit": if unit is None: propVal = "none" else: measures = unit.measures if measures[1]: propVal = 'mul {}\ndiv {} '.format( ', '.join(measureFormat(m) for m in measures[0]), ', '.join(measureFormat(m) for m in measures[1])) else: propVal = ', '.join(measureFormat(m) for m in measures[0]) if propVal is not None: fmtArgs[param] = propVal
def viewConcept(self, concept, modelObject, labelPrefix, preferredLabel, indent, arcrole, relationshipSet, visited): try: if concept is None: return isRelation = isinstance(modelObject, ModelRelationship) if isinstance(concept, ModelDtsObject.ModelConcept): text = labelPrefix + concept.label( preferredLabel, lang=self.lang, linkroleHint=relationshipSet.linkrole) if (self.arcrole in ("XBRL-dimensions", XbrlConst.hypercubeDimension) and concept.isTypedDimension and concept.typedDomainElement is not None): text += " (typedDomain={0})".format( concept.typedDomainElement.qname) xmlRowElementName = "concept" attr = {"name": str(concept.qname)} elif self.arcrole == "Table-rendering": text = concept.localName xmlRowElementName = "element" attr = {"label": concept.xlinkLabel} elif isinstance(concept, ModelDtsObject.ModelResource): if self.showReferences: text = (concept.viewText().strip() or concept.localName) attr = { "text": text, "innerXml": XmlUtil.xmlstring(concept, stripXmlns=True, prettyPrint=False, contentsOnly=True) } else: text = (concept.elementText.strip() or concept.localName) attr = {"text": text} xmlRowElementName = "resource" else: # just a resource text = concept.localName xmlRowElementName = text cols = [text] if isRelation: if arcrole == "XBRL-dimensions": # extra columns relArcrole = modelObject.arcrole cols.append(os.path.basename(relArcrole)) if relArcrole in (XbrlConst.all, XbrlConst.notAll): cols.append(modelObject.contextElement) cols.append(modelObject.closed) else: cols.append(None) cols.append(None) if relArcrole in (XbrlConst.dimensionDomain, XbrlConst.domainMember): cols.append(modelObject.usable) if self.arcrole == XbrlConst.parentChild: # extra columns cols.append(concept.niceType) cols.append(concept.viewReferences(concept)) elif arcrole == XbrlConst.summationItem: if isRelation: cols.append("{:0g} ".format(modelObject.weight)) else: cols.append("") # no weight on roots cols.append(concept.balance) elif self.isResourceArcrole: # resource columns if isRelation: cols.append(modelObject.arcrole) else: cols.append("") # no weight on roots if isinstance(concept, ModelDtsObject.ModelResource): cols.append(concept.localName) cols.append(concept.role or '') cols.append(concept.xmlLang) self.addRow(cols, treeIndent=indent, xmlRowElementName=xmlRowElementName, xmlRowEltAttr=attr, xmlCol0skipElt=True) if concept not in visited: visited.add(concept) for modelRel in relationshipSet.fromModelObject(concept): nestedRelationshipSet = relationshipSet targetRole = modelRel.targetRole if arcrole == XbrlConst.summationItem: childPrefix = "({:0g}) ".format( modelRel.weight ) # format without .0 on integer weights elif targetRole is None or len(targetRole) == 0: targetRole = relationshipSet.linkrole childPrefix = "" else: nestedRelationshipSet = self.modelXbrl.relationshipSet( arcrole, targetRole) childPrefix = "(via targetRole) " toConcept = modelRel.toModelObject if toConcept in visited: childPrefix += "(loop) " self.viewConcept( toConcept, modelRel, childPrefix, (modelRel.preferredLabel or self.labelrole), indent + 1, arcrole, nestedRelationshipSet, visited) visited.remove(concept) except AttributeError: # bad relationship return
def validateFiling(val, modelXbrl): linkroleDefinitionStatementSheet = re.compile( r"[^-]+-\s+Statement\s+-\s+.*", # no restriction to type of statement re.IGNORECASE) if not hasattr(modelXbrl.modelDocument, "xmlDocument"): # not parsed return val._isStandardUri = {} modelXbrl.modelManager.disclosureSystem.loadStandardTaxonomiesDict() # find typedDomainRefs before validateXBRL pass val.typedDomainQnames = set() val.typedDomainElements = set() for modelConcept in modelXbrl.qnameConcepts.values(): if modelConcept.isTypedDimension: typedDomainElement = modelConcept.typedDomainElement if isinstance(typedDomainElement, ModelConcept): val.typedDomainQnames.add(typedDomainElement.qname) val.typedDomainElements.add(typedDomainElement) # note that some XFM tests are done by ValidateXbrl to prevent multiple node walks xbrlInstDoc = modelXbrl.modelDocument.xmlDocument.getroot() disclosureSystem = val.disclosureSystem disclosureSystemVersion = disclosureSystem.version modelXbrl.modelManager.showStatus( _("validating {0}").format(disclosureSystem.name)) val.modelXbrl.profileActivity() conceptsUsed = { } # key=concept object value=True if has presentation label labelsRelationshipSet = modelXbrl.relationshipSet(XbrlConst.conceptLabel) genLabelsRelationshipSet = modelXbrl.relationshipSet( XbrlConst.elementLabel) presentationRelationshipSet = modelXbrl.relationshipSet( XbrlConst.parentChild) referencesRelationshipSetWithProhibits = modelXbrl.relationshipSet( XbrlConst.conceptReference, includeProhibits=True) val.modelXbrl.profileActivity("... cache lbl, pre, ref relationships", minTimeToShow=1.0) val.validateLoggingSemantic = validateLoggingSemantic = ( modelXbrl.isLoggingEffectiveFor(level="WARNING-SEMANTIC") or modelXbrl.isLoggingEffectiveFor(level="ERROR-SEMANTIC")) # instance checks val.fileNameBasePart = None # prevent testing on fileNameParts if not instance or invalid val.fileNameDate = None val.entityRegistrantName = None val.requiredContext = None val.standardNamespaceConflicts = defaultdict(set) val.exhibitType = None # e.g., EX-101, EX-201 # entry point schema checks print("Starting entrypoiny schema checks") if modelXbrl.modelDocument.type == ModelDocument.Type.SCHEMA: # entry must have a P-link if not any(hrefElt.localName == "linkbaseRef" and hrefElt.get("{http://www.w3.org/1999/xlink}role") == "http://www.xbrl.org/2003/role/presentationLinkbaseRef" for hrefElt, hrefDoc, hrefId in modelXbrl.modelDocument.hrefObjects): modelXbrl.error( "SBR.NL.2.02.10.01", 'Entrypoint schema must have a presentation linkbase', modelObject=modelXbrl.modelDocument) # all-labels and references checks print("Starting labels and reference checks") for concept in modelXbrl.qnameConcepts.values(): conceptHasDefaultLangStandardLabel = False for modelLabelRel in labelsRelationshipSet.fromModelObject(concept): modelLabel = modelLabelRel.toModelObject role = modelLabel.role text = modelLabel.text lang = modelLabel.xmlLang if role == XbrlConst.documentationLabel: if concept.modelDocument.targetNamespace in disclosureSystem.standardTaxonomiesDict: modelXbrl.error( "SBR.NL.2.01.00.08", _("Concept %(concept)s of a standard taxonomy cannot have a documentation label: %(text)s" ), modelObject=modelLabel, concept=concept.qname, text=text) elif text and lang and disclosureSystem.defaultXmlLang and lang.startswith( disclosureSystem.defaultXmlLang): if role == XbrlConst.standardLabel: # merge of pre-plugin code per LOGIUS conceptHasDefaultLangStandardLabel = True match = modelXbrl.modelManager.disclosureSystem.labelCheckPattern.search( text) if match: modelXbrl.error( "SBR.NL.2.03.08.07", 'Label for concept %(concept)s role %(role)s has disallowed characters: "%(text)s"', modelObject=modelLabel, concept=concept.qname, role=role, text=match.group()) for modelRefRel in referencesRelationshipSetWithProhibits.fromModelObject( concept): modelReference = modelRefRel.toModelObject text = XmlUtil.innerText(modelReference) #6.18.1 no reference to company extension concepts if (concept.modelDocument.targetNamespace in disclosureSystem.standardTaxonomiesDict and not isStandardUri(val, modelRefRel.modelDocument.uri) ): # merge of pre-plugin code per LOGIUS #6.18.2 no extension to add or remove references to standard concepts modelXbrl.error( "SBR.NL.2.01.00.08", _("References for standard taxonomy concept %(concept)s are not allowed in an extension linkbase: %(text)s" ), modelObject=modelReference, concept=concept.qname, text=text, xml=XmlUtil.xmlstring(modelReference, stripXmlns=True, contentsOnly=True)) if concept.isItem or concept.isTuple: if concept.modelDocument.targetNamespace not in disclosureSystem.standardTaxonomiesDict: ''' Only continue if the concept's namespace is not a standard namespace. When using "--disclosureSystem SBR-NL" as load argument, this list is populated from 'config/sbr-nl-taxonomies.xml' ''' if not conceptHasDefaultLangStandardLabel: modelXbrl.error( "SBR.NL.2.02.02.26", _("Concept %(concept)s missing standard label in local language." ), modelObject=concept, concept=concept.qname) subsGroup = concept.get("substitutionGroup") if not concept.isAbstract: if subsGroup == "sbr:presentationItem" and not ( presentationRelationshipSet.toModelObject(concept) or presentationRelationshipSet.fromModelObject( concept)): modelXbrl.error( "SBR.NL.2.02.02.04", _("Concept %(concept)s not referred to by presentation relationship." ), modelObject=concept, concept=concept.qname) elif ((concept.isDimensionItem or (subsGroup and (subsGroup.endswith(":domainItem") or subsGroup.endswith(":domainMemberItem")))) and not (presentationRelationshipSet.toModelObject(concept) or presentationRelationshipSet.fromModelObject( concept))): modelXbrl.error( "SBR.NL.2.02.10.03", _("DTS concept %(concept)s not referred to by presentation relationship." ), modelObject=concept, concept=concept.qname) if (concept.substitutionGroupQname and concept.substitutionGroupQname.namespaceURI not in disclosureSystem.baseTaxonomyNamespaces): modelXbrl.error( "SBR.NL.2.02.02.05", _("Concept %(concept)s has a substitutionGroup of a non-standard concept." ), modelObject=concept, concept=concept.qname) if concept.isTuple: # verify same presentation linkbase nesting if concept.type is not None: for missingQname in set( concept.type.elements ) ^ pLinkedNonAbstractDescendantQnames( modelXbrl, concept): modelXbrl.error( "SBR.NL.2.03.04.01", _("Tuple %(concept)s has mismatch between content and presentation children: %(missingQname)s." ), modelObject=concept, concept=concept.qname, missingQname=missingQname) else: print(f"{concept.elementNamespaceURI}") checkConceptLabels(val, modelXbrl, labelsRelationshipSet, disclosureSystem, concept) checkConceptLabels(val, modelXbrl, genLabelsRelationshipSet, disclosureSystem, concept) val.modelXbrl.profileActivity("... filer concepts checks", minTimeToShow=1.0) # checks on all documents: instance, schema, instance checkFilingDTS(val, modelXbrl.modelDocument, []) ''' removed RH 2011-12-23, corresponding use of nameWordsTable in ValidateFilingDTS if val.validateSBRNL: del val.nameWordsTable ''' val.modelXbrl.profileActivity("... filer DTS checks", minTimeToShow=1.0) conceptRelsUsedWithPreferredLabels = defaultdict(list) usedCalcsPresented = defaultdict( set) # pairs of concepts objectIds used in calc usedCalcFromTosELR = {} localPreferredLabels = defaultdict(set) drsELRs = set() # do calculation, then presentation, then other arcroles val.summationItemRelsSetAllELRs = modelXbrl.relationshipSet( XbrlConst.summationItem) for arcroleFilter in (XbrlConst.summationItem, XbrlConst.parentChild, "*"): for baseSetKey, baseSetModelLinks in modelXbrl.baseSets.items(): arcrole, ELR, linkqname, arcqname = baseSetKey if ELR and linkqname and arcqname and not arcrole.startswith( "XBRL-"): # assure summationItem, then parentChild, then others if not (arcroleFilter == arcrole or arcroleFilter == "*" and arcrole not in (XbrlConst.summationItem, XbrlConst.parentChild)): continue if arcrole == XbrlConst.parentChild: ineffectiveArcs = ModelRelationshipSet.ineffectiveArcs( baseSetModelLinks, arcrole) #validate ineffective arcs for modelRel in ineffectiveArcs: if isinstance(modelRel.fromModelObject, ModelObject) and isinstance( modelRel.toModelObject, ModelObject): modelXbrl.error( "SBR.NL.2.03.04.06", _("Ineffective arc %(arc)s in \nlink role %(linkrole)s \narcrole %(arcrole)s \nfrom %(conceptFrom)s \nto %(conceptTo)s \n%(ineffectivity)s" ), modelObject=modelRel, arc=modelRel.qname, arcrole=modelRel.arcrole, linkrole=modelRel.linkrole, linkroleDefinition=modelXbrl. roleTypeDefinition(modelRel.linkrole), conceptFrom=modelRel.fromModelObject.qname, conceptTo=modelRel.toModelObject.qname, ineffectivity=modelRel.ineffectivity) if arcrole == XbrlConst.parentChild: isStatementSheet = any( linkroleDefinitionStatementSheet.match( roleType.definition or '') for roleType in val.modelXbrl.roleTypes.get(ELR, ())) conceptsPresented = set() # 6.12.2 check for distinct order attributes parentChildRels = modelXbrl.relationshipSet(arcrole, ELR) for relFrom, siblingRels in parentChildRels.fromModelObjects( ).items(): targetConceptPreferredLabels = defaultdict(dict) orderRels = {} firstRel = True relFromUsed = True for rel in siblingRels: if firstRel: firstRel = False if relFrom in conceptsUsed: conceptsUsed[ relFrom] = True # 6.12.3, has a pres relationship relFromUsed = True relTo = rel.toModelObject preferredLabel = rel.preferredLabel if relTo in conceptsUsed: conceptsUsed[ relTo] = True # 6.12.3, has a pres relationship if preferredLabel and preferredLabel != "": conceptRelsUsedWithPreferredLabels[ relTo].append(rel) if preferredLabel in ("periodStart", "periodEnd"): modelXbrl.error( "SBR.NL.2.03.04.03", _("Preferred label on presentation relationships not allowed" ), modelObject=modelRel) # 6.12.5 distinct preferred labels in base set preferredLabels = targetConceptPreferredLabels[ relTo] if (preferredLabel in preferredLabels or (not relFrom.isTuple and (not preferredLabel or None in preferredLabels))): if preferredLabel in preferredLabels: rel2, relTo2 = preferredLabels[ preferredLabel] else: rel2 = relTo2 = None modelXbrl.error( "SBR.NL.2.03.04.06", _("Concept %(concept)s has duplicate preferred label %(preferredLabel)s in link role %(linkrole)s" ), modelObject=(rel, relTo, rel2, relTo2), concept=relTo.qname, fromConcept=rel.fromModelObject.qname, preferredLabel=preferredLabel, linkrole=rel.linkrole, linkroleDefinition=modelXbrl. roleTypeDefinition(rel.linkrole)) else: preferredLabels[preferredLabel] = (rel, relTo) if relFromUsed: # 6.14.5 conceptsPresented.add(relFrom.objectIndex) conceptsPresented.add(relTo.objectIndex) order = rel.order if order in orderRels: modelXbrl.error( "SBR.NL.2.03.04.05", _("Duplicate presentation relations from concept %(conceptFrom)s for order %(order)s in base set role %(linkrole)s to concept %(conceptTo)s and to concept %(conceptTo2)s" ), modelObject=(rel, orderRels[order]), conceptFrom=relFrom.qname, order=rel.arcElement.get("order"), linkrole=rel.linkrole, linkroleDefinition=modelXbrl. roleTypeDefinition(rel.linkrole), conceptTo=rel.toModelObject.qname, conceptTo2=orderRels[order].toModelObject. qname) else: orderRels[order] = rel if not relFrom.isTuple: if relTo in localPreferredLabels: if {None, preferredLabel } & localPreferredLabels[relTo]: val.modelXbrl.error( "SBR.NL.2.03.04.06", _("Non-distinguished preferredLabel presentation relations from concept %(conceptFrom)s in base set role %(linkrole)s" ), modelObject=rel, conceptFrom=relFrom.qname, linkrole=rel.linkrole, conceptTo=relTo.qname) localPreferredLabels[relTo].add(preferredLabel) targetConceptPreferredLabels.clear() orderRels.clear() localPreferredLabels.clear() # clear for next relationship for conceptPresented in conceptsPresented: if conceptPresented in usedCalcsPresented: usedCalcPairingsOfConcept = usedCalcsPresented[ conceptPresented] if len(usedCalcPairingsOfConcept & conceptsPresented) > 0: usedCalcPairingsOfConcept -= conceptsPresented elif arcrole == XbrlConst.summationItem: # find a calc relationship to get the containing document name for modelRel in val.modelXbrl.relationshipSet( arcrole, ELR).modelRelationships: val.modelXbrl.error( "SBR.NL.2.03.09.01", _("Calculation linkbase linkrole %(linkrole)s"), modelObject=modelRel, linkrole=ELR) break elif arcrole == XbrlConst.all or arcrole == XbrlConst.notAll: drsELRs.add(ELR) else: if arcrole == XbrlConst.dimensionDefault: for modelRel in val.modelXbrl.relationshipSet( arcrole).modelRelationships: val.modelXbrl.error( "SBR.NL.2.03.06.05", _("Dimension-default in from %(conceptFrom)s to %(conceptTo)s in role %(linkrole)s is not allowed" ), modelObject=modelRel, conceptFrom=modelRel.fromModelObject.qname, conceptTo=modelRel.toModelObject.qname, linkrole=modelRel.linkrole) ''' removed per RH 2013-01-11 if not (XbrlConst.isStandardArcrole(arcrole) or XbrlConst.isDefinitionOrXdtArcrole(arcrole)): for modelRel in val.modelXbrl.relationshipSet(arcrole).modelRelationships: relTo = modelRel.toModelObject relFrom = modelRel.fromModelObject if not ((isinstance(relFrom,ModelConcept) and isinstance(relTo,ModelConcept)) or (relFrom.modelDocument.inDTS and (relTo.qname == XbrlConst.qnGenLabel and modelRel.arcrole == XbrlConst.elementLabel) or (relTo.qname == XbrlConst.qnGenReference and modelRel.arcrole == XbrlConst.elementReference) or (relTo.qname == val.qnSbrLinkroleorder))): val.modelXbrl.error("SBR.NL.2.3.2.07", _("The source and target of an arc must be in the DTS from %(elementFrom)s to %(elementTo)s, in linkrole %(linkrole)s, arcrole %(arcrole)s"), modelObject=modelRel, elementFrom=relFrom.qname, elementTo=relTo.qname, linkrole=modelRel.linkrole, arcrole=arcrole) ''' del localPreferredLabels # dereference del usedCalcFromTosELR del val.summationItemRelsSetAllELRs val.modelXbrl.profileActivity("... filer relationships checks", minTimeToShow=1.0) # checks on dimensions checkFilingDimensions(val, drsELRs) val.modelXbrl.profileActivity("... filer dimensions checks", minTimeToShow=1.0) del conceptRelsUsedWithPreferredLabels # 6 16 4, 1.16.5 Base sets of Domain Relationship Sets testing val.modelXbrl.profileActivity("... filer preferred label checks", minTimeToShow=1.0) # moved from original validateSBRnl finally for qname, modelType in modelXbrl.qnameTypes.items(): if qname.namespaceURI not in val.disclosureSystem.baseTaxonomyNamespaces: facets = modelType.facets if facets: lengthFacets = _DICT_SET( facets.keys()) & {"minLength", "maxLength", "length"} if lengthFacets: modelXbrl.error( "SBR.NL.2.02.07.02", _("Type %(typename)s has length restriction facets %(facets)s" ), modelObject=modelType, typename=modelType.qname, facets=", ".join(lengthFacets)) if "enumeration" in facets and not modelType.isDerivedFrom( XbrlConst.qnXbrliStringItemType): modelXbrl.error( "SBR.NL.2.02.07.04", _("Concept %(concept)s has enumeration and is not based on stringItemType" ), modelObject=modelType, concept=modelType.qname) # check presentation link roles for generic linkbase order number ordersRelationshipSet = modelXbrl.relationshipSet( "http://www.nltaxonomie.nl/2011/arcrole/linkrole-order") presLinkroleNumberURI = {} presLinkrolesCount = 0 for countLinkroles in (True, False): for _roleURI, modelRoleTypes in modelXbrl.roleTypes.items(): for modelRoleType in modelRoleTypes: if XbrlConst.qnLinkPresentationLink in modelRoleType.usedOns: if countLinkroles: presLinkrolesCount += 1 else: if not ordersRelationshipSet: modelXbrl.error( "SBR.NL.2.02.03.06", _("Presentation linkrole %(linkrole)s missing order number relationship set" ), modelObject=modelRoleType, linkrole=modelRoleType.roleURI) else: order = None for orderNumRel in ordersRelationshipSet.fromModelObject( modelRoleType): order = getattr(orderNumRel.toModelObject, "xValue", "(noPSVIvalue)") if order in presLinkroleNumberURI: modelXbrl.error( "SBR.NL.2.02.03.06", _("Presentation linkrole order number %(order)s of %(linkrole)s also used in %(otherLinkrole)s" ), modelObject=modelRoleType, order=order, linkrole=modelRoleType.roleURI, otherLinkrole=presLinkroleNumberURI[ order]) else: presLinkroleNumberURI[ order] = modelRoleType.roleURI if not order: modelXbrl.error( "SBR.NL.2.02.03.06", _("Presentation linkrole %(linkrole)s missing order number" ), modelObject=modelRoleType, linkrole=modelRoleType.roleURI) if countLinkroles and presLinkrolesCount < 2: break # don't check order numbers if only one presentation linkrole # check arc role definitions for labels for arcroleURI, modelRoleTypes in modelXbrl.arcroleTypes.items(): for modelRoleType in modelRoleTypes: if (not arcroleURI.startswith("http://xbrl.org/") and modelRoleType.modelDocument.targetNamespace not in val.disclosureSystem.baseTaxonomyNamespaces and (not modelRoleType.genLabel(lang="nl") or not modelRoleType.genLabel(lang="en"))): modelXbrl.error( "SBR.NL.2.02.04.02", _("ArcroleType missing nl or en generic label: %(arcrole)s" ), modelObject=modelRoleType, arcrole=arcroleURI) for domainElt in val.typedDomainElements: if domainElt.modelDocument.targetNamespace not in val.disclosureSystem.baseTaxonomyNamespaces: if not domainElt.genLabel(fallbackToQname=False, lang="nl"): modelXbrl.error( "SBR.NL.2.02.08.01", _("Typed dimension domain element %(concept)s must have a generic label" ), modelObject=domainElt, concept=domainElt.qname) if domainElt.type is not None and domainElt.type.localName == "complexType": modelXbrl.error( "SBR.NL.2.02.08.02", _("Typed dimension domain element %(concept)s has disallowed complex content" ), modelObject=domainElt, concept=domainElt.qname) modelXbrl.profileActivity("... SBR role types and type facits checks", minTimeToShow=1.0) # end moved from ValidateFiling # 3.2.4.4 check each using prefix against taxonomy declaring the prefix for docs in modelXbrl.namespaceDocs.values(): for doc in docs: for prefix, NS in doc.xmlRootElement.nsmap.items(): if NS in val.namespacePrefix and prefix != val.namespacePrefix[ NS]: modelXbrl.error( "SBR.NL.3.02.04.04", _("The assigned namespace prefix %(assignedPrefix)s for the schema that declares the targetnamespace %(namespace)s, MUST be adhired by all other NT schemas, referencedPrefix: %(referencedPrefix)s" ), modelObject=doc.xmlRootElement, namespace=NS, assignedPrefix=val.namespacePrefix.get(NS, ''), referencedPrefix=prefix) # check non-concept elements that can appear in elements for labels (concepts checked by labelsRelationshipSet = modelXbrl.relationshipSet( (XbrlConst.conceptLabel, XbrlConst.elementLabel)) baseTaxonomyNamespaces = val.disclosureSystem.baseTaxonomyNamespaces for eltDef in modelXbrl.qnameConcepts.values(): if (not (eltDef.isItem or eltDef.isTuple or eltDef.isLinkPart) and eltDef.qname.namespaceURI not in baseTaxonomyNamespaces): eltDefHasDefaultLangStandardLabel = False for modelLabelRel in labelsRelationshipSet.fromModelObject(eltDef): modelLabel = modelLabelRel.toModelObject role = modelLabel.role text = modelLabel.text lang = modelLabel.xmlLang if text and lang and val.disclosureSystem.defaultXmlLang and lang.startswith( val.disclosureSystem.defaultXmlLang): if role in (XbrlConst.standardLabel, XbrlConst.genStandardLabel): eltDefHasDefaultLangStandardLabel = True if not eltDefHasDefaultLangStandardLabel: modelXbrl.error( "SBR.NL.3.02.15.01", _("XML nodes that can appear in instances MUST have standard labels in the local language: %(element)s" ), modelObject=eltDef, element=eltDef.qname) val.modelXbrl.profileStat( _("validate{0}").format( modelXbrl.modelManager.disclosureSystem.validationType)) modelXbrl.modelManager.showStatus(_("ready"), 2000)
def ordinateView(self): return XmlUtil.xmlstring(self, stripXmlns=True, prettyPrint=True)
def validateFiling(val, modelXbrl): linkroleDefinitionStatementSheet = re.compile(r"[^-]+-\s+Statement\s+-\s+.*", # no restriction to type of statement re.IGNORECASE) if not hasattr(modelXbrl.modelDocument, "xmlDocument"): # not parsed return val._isStandardUri = {} modelXbrl.modelManager.disclosureSystem.loadStandardTaxonomiesDict() # find typedDomainRefs before validateXBRL pass val.typedDomainQnames = set() val.typedDomainElements = set() for modelConcept in modelXbrl.qnameConcepts.values(): if modelConcept.isTypedDimension: typedDomainElement = modelConcept.typedDomainElement if isinstance(typedDomainElement, ModelConcept): val.typedDomainQnames.add(typedDomainElement.qname) val.typedDomainElements.add(typedDomainElement) # note that some XFM tests are done by ValidateXbrl to prevent multiple node walks xbrlInstDoc = modelXbrl.modelDocument.xmlDocument.getroot() disclosureSystem = val.disclosureSystem disclosureSystemVersion = disclosureSystem.version modelXbrl.modelManager.showStatus(_("validating {0}").format(disclosureSystem.name)) val.modelXbrl.profileActivity() conceptsUsed = {} # key=concept object value=True if has presentation label labelsRelationshipSet = modelXbrl.relationshipSet(XbrlConst.conceptLabel) genLabelsRelationshipSet = modelXbrl.relationshipSet(XbrlConst.elementLabel) presentationRelationshipSet = modelXbrl.relationshipSet(XbrlConst.parentChild) referencesRelationshipSetWithProhibits = modelXbrl.relationshipSet(XbrlConst.conceptReference, includeProhibits=True) val.modelXbrl.profileActivity("... cache lbl, pre, ref relationships", minTimeToShow=1.0) val.validateLoggingSemantic = validateLoggingSemantic = ( modelXbrl.isLoggingEffectiveFor(level="WARNING-SEMANTIC") or modelXbrl.isLoggingEffectiveFor(level="ERROR-SEMANTIC")) # instance checks val.fileNameBasePart = None # prevent testing on fileNameParts if not instance or invalid val.fileNameDate = None val.entityRegistrantName = None val.requiredContext = None val.standardNamespaceConflicts = defaultdict(set) val.exhibitType = None # e.g., EX-101, EX-201 # entry point schema checks if modelXbrl.modelDocument.type == ModelDocument.Type.SCHEMA: # entry must have a P-link if not any(hrefElt.localName == "linkbaseRef" and hrefElt.get("{http://www.w3.org/1999/xlink}role") == "http://www.xbrl.org/2003/role/presentationLinkbaseRef" for hrefElt, hrefDoc, hrefId in modelXbrl.modelDocument.hrefObjects): modelXbrl.error("SBR.NL.2.2.10.01", 'Entrypoint schema must have a presentation linkbase', modelObject=modelXbrl.modelDocument) # all-labels and references checks for concept in modelXbrl.qnameConcepts.values(): conceptHasDefaultLangStandardLabel = False for modelLabelRel in labelsRelationshipSet.fromModelObject(concept): modelLabel = modelLabelRel.toModelObject role = modelLabel.role text = modelLabel.text lang = modelLabel.xmlLang if role == XbrlConst.documentationLabel: if concept.modelDocument.targetNamespace in disclosureSystem.standardTaxonomiesDict: modelXbrl.error("SBR.NL.2.1.0.08", _("Concept %(concept)s of a standard taxonomy cannot have a documentation label: %(text)s"), modelObject=modelLabel, concept=concept.qname, text=text) elif text and lang and disclosureSystem.defaultXmlLang and lang.startswith(disclosureSystem.defaultXmlLang): if role == XbrlConst.standardLabel: # merge of pre-plugin code per LOGIUS conceptHasDefaultLangStandardLabel = True match = modelXbrl.modelManager.disclosureSystem.labelCheckPattern.search(text) if match: modelXbrl.error("SBR.NL.2.3.8.07", 'Label for concept %(concept)s role %(role)s has disallowed characters: "%(text)s"', modelObject=modelLabel, concept=concept.qname, role=role, text=match.group()) for modelRefRel in referencesRelationshipSetWithProhibits.fromModelObject(concept): modelReference = modelRefRel.toModelObject text = XmlUtil.innerText(modelReference) #6.18.1 no reference to company extension concepts if (concept.modelDocument.targetNamespace in disclosureSystem.standardTaxonomiesDict and not isStandardUri(val, modelRefRel.modelDocument.uri)): # merge of pre-plugin code per LOGIUS #6.18.2 no extension to add or remove references to standard concepts modelXbrl.error("SBR.NL.2.1.0.08", _("References for standard taxonomy concept %(concept)s are not allowed in an extension linkbase: %(text)s"), modelObject=modelReference, concept=concept.qname, text=text, xml=XmlUtil.xmlstring(modelReference, stripXmlns=True, contentsOnly=True)) if concept.isItem or concept.isTuple: if concept.modelDocument.targetNamespace not in disclosureSystem.standardTaxonomiesDict: if not conceptHasDefaultLangStandardLabel: modelXbrl.error("SBR.NL.2.2.2.26", _("Concept %(concept)s missing standard label in local language."), modelObject=concept, concept=concept.qname) subsGroup = concept.get("substitutionGroup") if ((not concept.isAbstract or subsGroup == "sbr:presentationItem") and not (presentationRelationshipSet.toModelObject(concept) or presentationRelationshipSet.fromModelObject(concept))): modelXbrl.error("SBR.NL.2.2.2.04", _("Concept %(concept)s not referred to by presentation relationship."), modelObject=concept, concept=concept.qname) elif ((concept.isDimensionItem or (subsGroup and (subsGroup.endswith(":domainItem") or subsGroup.endswith(":domainMemberItem")))) and not (presentationRelationshipSet.toModelObject(concept) or presentationRelationshipSet.fromModelObject(concept))): modelXbrl.error("SBR.NL.2.2.10.03", _("DTS concept %(concept)s not referred to by presentation relationship."), modelObject=concept, concept=concept.qname) if (concept.substitutionGroupQname and concept.substitutionGroupQname.namespaceURI not in disclosureSystem.baseTaxonomyNamespaces): modelXbrl.error("SBR.NL.2.2.2.05", _("Concept %(concept)s has a substitutionGroup of a non-standard concept."), modelObject=concept, concept=concept.qname) if concept.isTuple: # verify same presentation linkbase nesting for missingQname in set(concept.type.elements) ^ pLinkedNonAbstractDescendantQnames(modelXbrl, concept): modelXbrl.error("SBR.NL.2.3.4.01", _("Tuple %(concept)s has mismatch between content and presentation children: %(missingQname)s."), modelObject=concept, concept=concept.qname, missingQname=missingQname) checkConceptLabels(val, modelXbrl, labelsRelationshipSet, disclosureSystem, concept) checkConceptLabels(val, modelXbrl, genLabelsRelationshipSet, disclosureSystem, concept) val.modelXbrl.profileActivity("... filer concepts checks", minTimeToShow=1.0) # checks on all documents: instance, schema, instance checkFilingDTS(val, modelXbrl.modelDocument, []) ''' removed RH 2011-12-23, corresponding use of nameWordsTable in ValidateFilingDTS if val.validateSBRNL: del val.nameWordsTable ''' val.modelXbrl.profileActivity("... filer DTS checks", minTimeToShow=1.0) conceptRelsUsedWithPreferredLabels = defaultdict(list) usedCalcsPresented = defaultdict(set) # pairs of concepts objectIds used in calc usedCalcFromTosELR = {} localPreferredLabels = defaultdict(set) drsELRs = set() # do calculation, then presentation, then other arcroles val.summationItemRelsSetAllELRs = modelXbrl.relationshipSet(XbrlConst.summationItem) for arcroleFilter in (XbrlConst.summationItem, XbrlConst.parentChild, "*"): for baseSetKey, baseSetModelLinks in modelXbrl.baseSets.items(): arcrole, ELR, linkqname, arcqname = baseSetKey if ELR and linkqname and arcqname and not arcrole.startswith("XBRL-"): # assure summationItem, then parentChild, then others if not (arcroleFilter == arcrole or arcroleFilter == "*" and arcrole not in (XbrlConst.summationItem, XbrlConst.parentChild)): continue if arcrole == XbrlConst.parentChild: ineffectiveArcs = ModelRelationshipSet.ineffectiveArcs(baseSetModelLinks, arcrole) #validate ineffective arcs for modelRel in ineffectiveArcs: if modelRel.fromModelObject is not None and modelRel.toModelObject is not None: modelXbrl.error("SBR.NL.2.3.4.06", _("Ineffective arc %(arc)s in \nlink role %(linkrole)s \narcrole %(arcrole)s \nfrom %(conceptFrom)s \nto %(conceptTo)s \n%(ineffectivity)s"), modelObject=modelRel, arc=modelRel.qname, arcrole=modelRel.arcrole, linkrole=modelRel.linkrole, linkroleDefinition=modelXbrl.roleTypeDefinition(modelRel.linkrole), conceptFrom=modelRel.fromModelObject.qname, conceptTo=modelRel.toModelObject.qname, ineffectivity=modelRel.ineffectivity) if arcrole == XbrlConst.parentChild: isStatementSheet = any(linkroleDefinitionStatementSheet.match(roleType.definition or '') for roleType in val.modelXbrl.roleTypes.get(ELR,())) conceptsPresented = set() # 6.12.2 check for distinct order attributes parentChildRels = modelXbrl.relationshipSet(arcrole, ELR) for relFrom, siblingRels in parentChildRels.fromModelObjects().items(): targetConceptPreferredLabels = defaultdict(dict) orderRels = {} firstRel = True relFromUsed = True for rel in siblingRels: if firstRel: firstRel = False if relFrom in conceptsUsed: conceptsUsed[relFrom] = True # 6.12.3, has a pres relationship relFromUsed = True relTo = rel.toModelObject preferredLabel = rel.preferredLabel if relTo in conceptsUsed: conceptsUsed[relTo] = True # 6.12.3, has a pres relationship if preferredLabel and preferredLabel != "": conceptRelsUsedWithPreferredLabels[relTo].append(rel) if preferredLabel in ("periodStart","periodEnd"): modelXbrl.error("SBR.NL.2.3.4.03", _("Preferred label on presentation relationships not allowed"), modelObject=modelRel) # 6.12.5 distinct preferred labels in base set preferredLabels = targetConceptPreferredLabels[relTo] if (preferredLabel in preferredLabels or (not relFrom.isTuple and (not preferredLabel or None in preferredLabels))): if preferredLabel in preferredLabels: rel2, relTo2 = preferredLabels[preferredLabel] else: rel2 = relTo2 = None modelXbrl.error("SBR.NL.2.3.4.06", _("Concept %(concept)s has duplicate preferred label %(preferredLabel)s in link role %(linkrole)s"), modelObject=(rel, relTo, rel2, relTo2), concept=relTo.qname, fromConcept=rel.fromModelObject.qname, preferredLabel=preferredLabel, linkrole=rel.linkrole, linkroleDefinition=modelXbrl.roleTypeDefinition(rel.linkrole)) else: preferredLabels[preferredLabel] = (rel, relTo) if relFromUsed: # 6.14.5 conceptsPresented.add(relFrom.objectIndex) conceptsPresented.add(relTo.objectIndex) order = rel.order if order in orderRels: modelXbrl.error("SBR.NL.2.3.4.05", _("Duplicate presentation relations from concept %(conceptFrom)s for order %(order)s in base set role %(linkrole)s to concept %(conceptTo)s and to concept %(conceptTo2)s"), modelObject=(rel, orderRels[order]), conceptFrom=relFrom.qname, order=rel.arcElement.get("order"), linkrole=rel.linkrole, linkroleDefinition=modelXbrl.roleTypeDefinition(rel.linkrole), conceptTo=rel.toModelObject.qname, conceptTo2=orderRels[order].toModelObject.qname) else: orderRels[order] = rel if not relFrom.isTuple: if relTo in localPreferredLabels: if {None, preferredLabel} & localPreferredLabels[relTo]: val.modelXbrl.error("SBR.NL.2.3.4.06", _("Non-distinguished preferredLabel presentation relations from concept %(conceptFrom)s in base set role %(linkrole)s"), modelObject=rel, conceptFrom=relFrom.qname, linkrole=rel.linkrole, conceptTo=relTo.qname) localPreferredLabels[relTo].add(preferredLabel) targetConceptPreferredLabels.clear() orderRels.clear() localPreferredLabels.clear() # clear for next relationship for conceptPresented in conceptsPresented: if conceptPresented in usedCalcsPresented: usedCalcPairingsOfConcept = usedCalcsPresented[conceptPresented] if len(usedCalcPairingsOfConcept & conceptsPresented) > 0: usedCalcPairingsOfConcept -= conceptsPresented elif arcrole == XbrlConst.summationItem: # find a calc relationship to get the containing document name for modelRel in val.modelXbrl.relationshipSet(arcrole, ELR).modelRelationships: val.modelXbrl.error("SBR.NL.2.3.9.01", _("Calculation linkbase linkrole %(linkrole)s"), modelObject=modelRel, linkrole=ELR) break elif arcrole == XbrlConst.all or arcrole == XbrlConst.notAll: drsELRs.add(ELR) else: if arcrole == XbrlConst.dimensionDefault: for modelRel in val.modelXbrl.relationshipSet(arcrole).modelRelationships: val.modelXbrl.error("SBR.NL.2.3.6.05", _("Dimension-default in from %(conceptFrom)s to %(conceptTo)s in role %(linkrole)s is not allowed"), modelObject=modelRel, conceptFrom=modelRel.fromModelObject.qname, conceptTo=modelRel.toModelObject.qname, linkrole=modelRel.linkrole) ''' removed per RH 2013-01-11 if not (XbrlConst.isStandardArcrole(arcrole) or XbrlConst.isDefinitionOrXdtArcrole(arcrole)): for modelRel in val.modelXbrl.relationshipSet(arcrole).modelRelationships: relTo = modelRel.toModelObject relFrom = modelRel.fromModelObject if not ((isinstance(relFrom,ModelConcept) and isinstance(relTo,ModelConcept)) or (relFrom.modelDocument.inDTS and (relTo.qname == XbrlConst.qnGenLabel and modelRel.arcrole == XbrlConst.elementLabel) or (relTo.qname == XbrlConst.qnGenReference and modelRel.arcrole == XbrlConst.elementReference) or (relTo.qname == val.qnSbrLinkroleorder))): val.modelXbrl.error("SBR.NL.2.3.2.07", _("The source and target of an arc must be in the DTS from %(elementFrom)s to %(elementTo)s, in linkrole %(linkrole)s, arcrole %(arcrole)s"), modelObject=modelRel, elementFrom=relFrom.qname, elementTo=relTo.qname, linkrole=modelRel.linkrole, arcrole=arcrole) ''' del localPreferredLabels # dereference del usedCalcFromTosELR del val.summationItemRelsSetAllELRs val.modelXbrl.profileActivity("... filer relationships checks", minTimeToShow=1.0) # checks on dimensions checkFilingDimensions(val, drsELRs) val.modelXbrl.profileActivity("... filer dimensions checks", minTimeToShow=1.0) del conceptRelsUsedWithPreferredLabels # 6 16 4, 1.16.5 Base sets of Domain Relationship Sets testing val.modelXbrl.profileActivity("... filer preferred label checks", minTimeToShow=1.0) # moved from original validateSBRnl finally for qname, modelType in modelXbrl.qnameTypes.items(): if qname.namespaceURI not in val.disclosureSystem.baseTaxonomyNamespaces: facets = modelType.facets if facets: lengthFacets = _DICT_SET(facets.keys()) & {"minLength", "maxLength", "length"} if lengthFacets: modelXbrl.error("SBR.NL.2.2.7.02", _("Type %(typename)s has length restriction facets %(facets)s"), modelObject=modelType, typename=modelType.qname, facets=", ".join(lengthFacets)) if "enumeration" in facets and not modelType.isDerivedFrom(XbrlConst.qnXbrliStringItemType): modelXbrl.error("SBR.NL.2.2.7.04", _("Concept %(concept)s has enumeration and is not based on stringItemType"), modelObject=modelType, concept=modelType.qname) ''' removed RH 2011-12-23, corresponding use of nameWordsTable in ValidateFilingDTS # build camelCasedNamesTable self.nameWordsTable = {} for name in modelXbrl.nameConcepts.keys(): words = [] wordChars = [] lastchar = "" for c in name: if c.isupper() and lastchar.islower(): # it's another word partialName = ''.join(wordChars) if partialName in modelXbrl.nameConcepts: words.append(partialName) wordChars.append(c) lastchar = c if words: self.nameWordsTable[name] = words self.modelXbrl.profileActivity("... build name words table", minTimeToShow=1.0) ''' # check presentation link roles for generic linkbase order number ordersRelationshipSet = modelXbrl.relationshipSet("http://www.nltaxonomie.nl/2011/arcrole/linkrole-order") presLinkroleNumberURI = {} presLinkrolesCount = 0 for countLinkroles in (True, False): for _roleURI, modelRoleTypes in modelXbrl.roleTypes.items(): for modelRoleType in modelRoleTypes: if XbrlConst.qnLinkPresentationLink in modelRoleType.usedOns: if countLinkroles: presLinkrolesCount += 1 else: if not ordersRelationshipSet: modelXbrl.error("SBR.NL.2.2.3.06", _("Presentation linkrole %(linkrole)s missing order number relationship set"), modelObject=modelRoleType, linkrole=modelRoleType.roleURI) else: order = None for orderNumRel in ordersRelationshipSet.fromModelObject(modelRoleType): order = getattr(orderNumRel.toModelObject, "xValue", "(noPSVIvalue)") if order in presLinkroleNumberURI: modelXbrl.error("SBR.NL.2.2.3.06", _("Presentation linkrole order number %(order)s of %(linkrole)s also used in %(otherLinkrole)s"), modelObject=modelRoleType, order=order, linkrole=modelRoleType.roleURI, otherLinkrole=presLinkroleNumberURI[order]) else: presLinkroleNumberURI[order] = modelRoleType.roleURI if not order: modelXbrl.error("SBR.NL.2.2.3.06", _("Presentation linkrole %(linkrole)s missing order number"), modelObject=modelRoleType, linkrole=modelRoleType.roleURI) if countLinkroles and presLinkrolesCount < 2: break # don't check order numbers if only one presentation linkrole # check arc role definitions for labels for arcroleURI, modelRoleTypes in modelXbrl.arcroleTypes.items(): for modelRoleType in modelRoleTypes: if (not arcroleURI.startswith("http://xbrl.org/") and modelRoleType.modelDocument.targetNamespace not in val.disclosureSystem.baseTaxonomyNamespaces and (not modelRoleType.genLabel(lang="nl") or not modelRoleType.genLabel(lang="en"))): modelXbrl.error("SBR.NL.2.2.4.02", _("ArcroleType missing nl or en generic label: %(arcrole)s"), modelObject=modelRoleType, arcrole=arcroleURI) for domainElt in val.typedDomainElements: if domainElt.modelDocument.targetNamespace not in val.disclosureSystem.baseTaxonomyNamespaces: if not domainElt.genLabel(fallbackToQname=False, lang="nl"): modelXbrl.error("SBR.NL.2.2.8.01", _("Typed dimension domain element %(concept)s must have a generic label"), modelObject=domainElt, concept=domainElt.qname) if domainElt.type is not None and domainElt.type.localName == "complexType": modelXbrl.error("SBR.NL.2.2.8.02", _("Typed dimension domain element %(concept)s has disallowed complex content"), modelObject=domainElt, concept=domainElt.qname) modelXbrl.profileActivity("... SBR role types and type facits checks", minTimeToShow=1.0) # end moved from ValidateFiling # 3.2.4.4 check each using prefix against taxonomy declaring the prefix for docs in modelXbrl.namespaceDocs.values(): for doc in docs: for prefix, NS in doc.xmlRootElement.nsmap.items(): if NS in val.namespacePrefix and prefix != val.namespacePrefix[NS]: modelXbrl.error("SBR.NL.3.2.4.04", _("The assigned namespace prefix %(assignedPrefix)s for the schema that declares the targetnamespace %(namespace)s, MUST be adhired by all other NT schemas, referencedPrefix: %(referencedPrefix)s"), modelObject=doc.xmlRootElement, namespace=NS, assignedPrefix=val.namespacePrefix.get(NS, ''), referencedPrefix=prefix) # check non-concept elements that can appear in elements for labels (concepts checked by labelsRelationshipSet = modelXbrl.relationshipSet((XbrlConst.conceptLabel, XbrlConst.elementLabel)) baseTaxonomyNamespaces = val.disclosureSystem.baseTaxonomyNamespaces for eltDef in modelXbrl.qnameConcepts.values(): if (not (eltDef.isItem or eltDef.isTuple or eltDef.isLinkPart) and eltDef.qname.namespaceURI not in baseTaxonomyNamespaces): eltDefHasDefaultLangStandardLabel = False for modelLabelRel in labelsRelationshipSet.fromModelObject(eltDef): modelLabel = modelLabelRel.toModelObject role = modelLabel.role text = modelLabel.text lang = modelLabel.xmlLang if text and lang and val.disclosureSystem.defaultXmlLang and lang.startswith(val.disclosureSystem.defaultXmlLang): if role in (XbrlConst.standardLabel, XbrlConst.genStandardLabel): eltDefHasDefaultLangStandardLabel = True if not eltDefHasDefaultLangStandardLabel: modelXbrl.error("SBR.NL.3.2.15.01", _("XML nodes that can appear in instances MUST have standard labels in the local language: %(element)s"), modelObject=eltDef, element=eltDef.qname) val.modelXbrl.profileStat(_("validate{0}").format(modelXbrl.modelManager.disclosureSystem.validationType)) modelXbrl.modelManager.showStatus(_("ready"), 2000)