def primaryItemQname(self): conceptRule = XmlUtil.child(self, XbrlConst.formula, "concept") if conceptRule is not None: qnameElt = XmlUtil.child(conceptRule, XbrlConst.formula, "qname") if qnameElt is not None: return qname(qnameElt, qnameElt.text) return None
def registryDiscover(self, rootNode): base = self.filepath for entryElement in rootNode.iterdescendants( tag="{http://xbrl.org/2008/registry}entry"): if isinstance(entryElement, ModelObject): uri = XmlUtil.childAttr(entryElement, XbrlConst.registry, "url", "{http://www.w3.org/1999/xlink}href") functionDoc = load(self.modelXbrl, uri, base=base, referringElement=entryElement) if functionDoc is not None: testUriElt = XmlUtil.child(functionDoc.xmlRootElement, XbrlConst.function, "conformanceTest") if testUriElt is not None: testuri = testUriElt.get( "{http://www.w3.org/1999/xlink}href") testbase = functionDoc.filepath if testuri is not None: testcaseDoc = load(self.modelXbrl, testuri, base=testbase, referringElement=testUriElt) if testcaseDoc is not None and self.referencesDocument.get( testcaseDoc) is None: self.referencesDocument[ testcaseDoc] = "registryIndex"
def __hash__(self): if self.isExplicit: return hash((self.dimensionQname, self.memberQname)) else: # need XPath equal so that QNames aren't lexically compared (for fact and context equality in comparing formula results) return hash((self.dimensionQname, XbrlUtil.equalityHash(XmlUtil.child(self), equalMode=XbrlUtil.XPATH_EQ)))
def resultIsTable(self): result = XmlUtil.descendant(self, None, "result") if result is not None : child = XmlUtil.child(result, None, "table") if child is not None and XmlUtil.text(child).endswith(".xml"): return True return False
def entityIdentifierElement(self): try: return self._entityIdentifierElement except AttributeError: self._entityIdentifierElement = XmlUtil.child( self.entity, XbrlConst.xbrli, "identifier") return self._entityIdentifierElement
def entityIdentifierElement(self): """(ModelObject) -- entity identifier element""" try: return self._entityIdentifierElement except AttributeError: self._entityIdentifierElement = XmlUtil.child(self.entity, XbrlConst.xbrli, "identifier") return self._entityIdentifierElement
def startDatetime(self): """(datetime) -- startDate attribute""" try: return self._startDatetime except AttributeError: self._startDatetime = XmlUtil.datetimeValue(XmlUtil.child(self.period, XbrlConst.xbrli, "startDate")) return self._startDatetime
def resultTableUri(self): result = XmlUtil.descendant(self, None, "result") if result is not None: child = XmlUtil.child(result, None, "table") if child is not None: return os.path.join(self.modelDocument.outpath, XmlUtil.text(child)) return None
def instantDatetime(self): """(datetime) -- instant attribute, with adjustment to end-of-day midnight as needed""" try: return self._instantDatetime except AttributeError: self._instantDatetime = XmlUtil.datetimeValue(XmlUtil.child(self.period, XbrlConst.xbrli, "instant"), addOneDay=True) return self._instantDatetime
def period(self): """(ModelObject) -- period element""" try: return self._period except AttributeError: self._period = XmlUtil.child(self, XbrlConst.xbrli, "period") return self._period
def entity(self): """(ModelObject) -- entity element""" try: return self._entity except AttributeError: self._entity = XmlUtil.child(self, XbrlConst.xbrli, "entity") return self._entity
def fromConceptQname(self): fromConcept = XmlUtil.child(self.element, XbrlConst.vercb, "fromConcept") if fromConcept and fromConcept.hasAttribute("name"): return qname(fromConcept, fromConcept.getAttribute("name")) else: return None
def definition(self): try: return self._definition except AttributeError: definition = XmlUtil.child(self, XbrlConst.link, "definition") self._definition = definition.elementText.strip() if definition is not None else None return self._definition
def startDatetime(self): try: return self._startDatetime except AttributeError: self._startDatetime = XmlUtil.datetimeValue( XmlUtil.child(self.period, XbrlConst.xbrli, "startDate")) return self._startDatetime
def viewFacts(self, modelFacts, indent): for modelFact in modelFacts: concept = modelFact.concept xmlRowElementName = 'item' attr = {"name": str(modelFact.qname)} if concept is not None and self.isCol0Label: lbl = concept.label(preferredLabel=self.labelrole, lang=self.lang, linkroleHint=XbrlConst.defaultLinkRole) xmlCol0skipElt = False # provide label as a row element else: lbl = (modelFact.qname or modelFact.prefixedName) # defective inline facts may have no qname xmlCol0skipElt = True # name is an attribute, don't do it also as an element cols = [lbl] if concept is not None: if modelFact.isItem: for col in self.cols[1:]: if col == "Label": # label or name may be 2nd to nth col if name or label is 1st col cols.append( concept.label(preferredLabel=self.labelrole, lang=self.lang) ) elif col == "Name": cols.append( modelFact.qname ) elif col == "contextRef": cols.append( modelFact.contextID ) elif col == "unitRef": cols.append( modelFact.unitID ) elif col == "Dec": cols.append( modelFact.decimals ) elif col == "Prec": cols.append( modelFact.precision ) elif col == "Lang": cols.append( modelFact.xmlLang ) elif col == "Value": cols.append( "(nil)" if modelFact.xsiNil == "true" else modelFact.effectiveValue.strip() ) elif col == "EntityScheme": cols.append( modelFact.context.entityIdentifier[0] ) elif col == "EntityIdentifier": cols.append( modelFact.context.entityIdentifier[1] ) elif col == "Start": cols.append( XmlUtil.text(XmlUtil.child(modelFact.context.period, XbrlConst.xbrli, "startDate")) ) elif col == "End/Instant": cols.append( XmlUtil.text(XmlUtil.child(modelFact.context.period, XbrlConst.xbrli, ("endDate","instant"))) ) elif col == "Dimensions": for dimQname in sorted(modelFact.context.qnameDims.keys()): cols.append( str(dimQname) ) cols.append( str(modelFact.context.dimMemberQname(dimQname)) ) elif modelFact.isTuple: xmlRowElementName = 'tuple' self.addRow(cols, treeIndent=indent, xmlRowElementName=xmlRowElementName, xmlRowEltAttr=attr, xmlCol0skipElt=xmlCol0skipElt) self.viewFacts(modelFact.modelTupleFacts, indent + 1)
def resultInfosetUri(self): result = XmlUtil.descendant(self, None, "result") if result is not None: child = XmlUtil.child(result, None, "file") return os.path.join( self.modelDocument.outpath, XmlUtil.text(child if child is not None else result)) return None
def resultIsInfoset(self): if self.modelDocument.outpath: result = XmlUtil.descendant(self, None, "result") if result is not None: return XmlUtil.child(result, None, "file") is not None or XmlUtil.text( result).endswith(".xml") return False
def instantDatetime(self): try: return self._instantDatetime except AttributeError: self._instantDatetime = XmlUtil.datetimeValue(XmlUtil.child( self.period, XbrlConst.xbrli, "instant"), addOneDay=True) return self._instantDatetime
def definition(self): try: return self._definition except AttributeError: definition = XmlUtil.child(self, XbrlConst.link, "definition") self._definition = definition.elementText.strip( ) if definition is not None else None return self._definition
def fromConceptQname(self): fromConcept = XmlUtil.child( self, None, "fromConcept" ) # can be vercu or vercb, schema validation will assure right elements if fromConcept is not None and fromConcept.get("name"): return qname(fromConcept, fromConcept.get("name")) else: return None
def viewFacts(self, modelFacts, indent): for modelFact in modelFacts: concept = modelFact.concept if concept is not None and self.isCol0Label: lbl = concept.label(lang=self.lang) else: lbl = modelFact.qname cols = indent + [lbl] for i in range(self.treeCols - len(cols)): cols.append(None) if concept is not None and not modelFact.concept.isTuple: for col in self.cols[1:]: if col == "contextRef": cols.append( modelFact.contextID ) elif col == "unitRef": cols.append( modelFact.unitID ) elif col == "Dec": cols.append( modelFact.decimals ) elif col == "Prec": cols.append( modelFact.precision ) elif col == "Lang": cols.append( modelFact.xmlLang ) elif col == "Value": cols.append( "(nil)" if modelFact.xsiNil == "true" else modelFact.effectiveValue.strip() ) elif col == "EntityScheme": cols.append( modelFact.context.entityIdentifier[0] ) elif col == "EntityIdentifier": cols.append( modelFact.context.entityIdentifier[1] ) elif col == "Start": cols.append( XmlUtil.text(XmlUtil.child(modelFact.context.period, XbrlConst.xbrli, "startDate")) ) elif col == "End/Instant": cols.append( XmlUtil.text(XmlUtil.child(modelFact.context.period, XbrlConst.xbrli, ("endDate","instant"))) ) elif col == "Dimensions": for dimQname in sorted(modelFact.context.qnameDims.keys()): cols.append( str(dimQname) ) cols.append( str(modelFact.context.dimMemberQname(dimQname)) ) self.write(cols) self.viewFacts(modelFact.modelTupleFacts, indent + [None])
def period_datetime(p, args, periodElement, addOneDay): if len(args) != 1: raise XPathContext.FunctionNumArgs() if len(args[0]) != 1: raise XPathContext.FunctionArgType(1,"xbrl:period") period = args[0][0] if (isinstance(period,xml.dom.Node) and period.nodeType == 1 and period.localName == "period" and period.namespaceURI == XbrlConst.xbrli): child = XmlUtil.child(period, XbrlConst.xbrli, periodElement) if child: return dateTime( child, addOneDay=addOneDay, type=DATETIME) elif periodElement == "instant": raise XPathContext.XPathException(p, 'xfie:PeriodIsNotInstant', _('Period is not instant')) else: raise XPathContext.XPathException(p, 'xfie:PeriodIsForever', _('Period is forever')) raise XPathContext.FunctionArgType(1,"xbrl:period")
def registryDiscover(self, rootNode): base = self.filepath for entryElement in rootNode.iterdescendants(tag="{http://xbrl.org/2008/registry}entry"): if isinstance(entryElement,ModelObject): uri = XmlUtil.childAttr(entryElement, XbrlConst.registry, "url", "{http://www.w3.org/1999/xlink}href") functionDoc = load(self.modelXbrl, uri, base=base, referringElement=entryElement) if functionDoc is not None: testUriElt = XmlUtil.child(functionDoc.xmlRootElement, XbrlConst.function, "conformanceTest") if testUriElt is not None: testuri = testUriElt.get("{http://www.w3.org/1999/xlink}href") testbase = functionDoc.filepath if testuri is not None: testcaseDoc = load(self.modelXbrl, testuri, base=testbase, referringElement=testUriElt) if testcaseDoc is not None and self.referencesDocument.get(testcaseDoc) is None: self.referencesDocument[testcaseDoc] = "registryIndex"
def viewTestGroup(self, group, parentNode, n): node = self.treeView.insert(parentNode, "end", group.objectId(), text=group.get("name"), tags=("odd" if n & 1 else "even",)) titleElt = XmlUtil.child(group, None, "title") if titleElt is not None: self.treeView.set(node, "name", titleElt.text) self.id += 1; i = -1 for elt in group.iterchildren(tag="{http://www.w3.org/2005/02/query-test-XQTSCatalog}test-group"): i = i + 1 self.viewTestGroup(elt, node, n + i + 1) for elt in group.iterchildren(tag="{http://www.w3.org/2005/02/query-test-XQTSCatalog}test-case"): if elt.get("is-XPath2") == "true": i = i + 1 self.viewTestcaseVariation(elt, node, n + i + 1)
def parent_child(args, parentName, descendantName): if len(args) != 1: raise XPathContext.FunctionNumArgs() if len(args[0]) != 1: raise XPathContext.FunctionArgType(1,"xbrl:" + parentName) parent = args[0][0] if isinstance(parent,ModelObject.ModelObject): parent = parent.element if isinstance(parent,xml.dom.Node) and parent.nodeType == 1 and \ parent.localName == parentName and parent.namespaceURI == XbrlConst.xbrli: if descendantName.startswith('@'): return parent.getAttribute(descendantName[1:]) elif descendantName == 'text()': return XmlUtil.text(parent) elif descendantName == 'strip-text()': return XmlUtil.text(parent).strip() else: return XmlUtil.child(parent, XbrlConst.xbrli, descendantName) raise XPathContext.FunctionArgType(1,"xbrl:" + parentName)
def createFilingIndicatorsElement(modelXbrl, newFactItemOptions): modelXbrl.createContext( newFactItemOptions.entityIdentScheme, newFactItemOptions.entityIdentValue, 'instant', None, newFactItemOptions.endDateDate, None, # no dimensional validity checking (like formula does) {}, [], [], id='c', afterSibling=ModelXbrl.AUTO_LOCATE_ELEMENT) # should place the filing indicators before any other fact # but after the following sequence: schemaRef, linkbaseRef, roleRef, arcroleRef parent = modelXbrl.modelDocument.xmlRootElement if parent is not None: child = XmlUtil.child(parent) if child is not None: beforeSibling = child afterSibling = None if str(child.qname) == "link:schemaRef": afterSibling = child child = child.getnext() if child is not None: if str(child.qname) == "link:linkbaseRef": afterSibling = child child = child.getnext() if child is not None: if str(child.qname) == "link:roleRef": afterSibling = child child = child.getnext() if child is not None: if str(child.qname) == "link:arcroleRef": afterSibling = child if afterSibling is not None: beforeSibling = None filingIndicatorsTuple = modelXbrl.createFact( qnFindFilingIndicators, validate=False, afterSibling=afterSibling, beforeSibling=beforeSibling) return filingIndicatorsTuple filingIndicatorsTuple = modelXbrl.createFact(qnFindFilingIndicators, validate=False) return filingIndicatorsTuple
def parent_child(args, parentName, descendantName): if len(args) != 1: raise XPathContext.FunctionNumArgs() if len(args[0]) != 1: raise XPathContext.FunctionArgType(1, "xbrl:" + parentName) parent = args[0][0] if isinstance(parent, ModelObject.ModelObject): parent = parent.element if isinstance(parent,xml.dom.Node) and parent.nodeType == 1 and \ parent.localName == parentName and parent.namespaceURI == XbrlConst.xbrli: if descendantName.startswith('@'): return parent.getAttribute(descendantName[1:]) elif descendantName == 'text()': return XmlUtil.text(parent) elif descendantName == 'strip-text()': return XmlUtil.text(parent).strip() else: return XmlUtil.child(parent, XbrlConst.xbrli, descendantName) raise XPathContext.FunctionArgType(1, "xbrl:" + parentName)
def parent_child(args, parentName, childName, findDescendant=False): if len(args) != 1: raise XPathContext.FunctionNumArgs() if len(args[0]) != 1: raise XPathContext.FunctionArgType(1,"xbrl:" + parentName) parent = args[0][0] if isinstance(parent,ModelObject) and \ parent.localName == parentName and parent.namespaceURI == XbrlConst.xbrli: if childName.startswith('@'): return parent.get(childName[1:]) elif childName == 'text()': return XmlUtil.textNotStripped(parent) elif childName == 'strip-text()': return XmlUtil.text(parent) elif findDescendant: return XmlUtil.descendant(parent, XbrlConst.xbrli, childName) else: return XmlUtil.child(parent, XbrlConst.xbrli, childName) raise XPathContext.FunctionArgType(1,"xbrl:" + parentName)
def period_datetime(p, args, periodElement, addOneDay): if len(args) != 1: raise XPathContext.FunctionNumArgs() if len(args[0]) != 1: raise XPathContext.FunctionArgType(1, "xbrl:period") period = args[0][0] if (isinstance(period, xml.dom.Node) and period.nodeType == 1 and period.localName == "period" and period.namespaceURI == XbrlConst.xbrli): child = XmlUtil.child(period, XbrlConst.xbrli, periodElement) if child: return dateTime(child, addOneDay=addOneDay, type=DATETIME) elif periodElement == "instant": raise XPathContext.XPathException(p, 'xfie:PeriodIsNotInstant', _('Period is not instant')) else: raise XPathContext.XPathException(p, 'xfie:PeriodIsForever', _('Period is forever')) raise XPathContext.FunctionArgType(1, "xbrl:period")
def propertyView(self): if self.isExplicit: return (str(self.dimensionQname), str(self.memberQname)) else: return (str(self.dimensionQname), etree.tounicode(XmlUtil.child(self)))
def toConceptQname(self): toConcept = XmlUtil.child(self, None, "toConcept") if toConcept is not None and toConcept.get("name"): return qname(toConcept, toConcept.get("name")) else: return None
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]) fmtArgs[param] = propVal
def relationshipSetElement(self): return XmlUtil.child(self.element, XbrlConst.verrels, "relationshipSet")
def customAttributeQname(self, eventName): custAttrElt = XmlUtil.child(self.element, XbrlConst.verce, eventName) if custAttrElt and custAttrElt.hasAttribute("name"): return qname(custAttrElt, custAttrElt.getAttribute("name")) return None
def relationshipSetElement(self): return XmlUtil.child(self, XbrlConst.verrels, "relationshipSet")
def entity(self): try: return self._entity except AttributeError: self._entity = XmlUtil.child(self, XbrlConst.xbrli, "entity") return self._entity
def validate(val, modelXbrl, infosetModelXbrl): infoset = infosetModelXbrl.modelDocument if infoset.type == Type.INSTANCE: # compare facts (assumed out of order) infosetFacts = defaultdict(list) for fact in infosetModelXbrl.facts: infosetFacts[fact.qname].append(fact) if len(modelXbrl.factsInInstance) != len( infosetModelXbrl.factsInInstance): modelXbrl.error( "arelle:infosetTest", _("Fact counts mismatch, testcase instance %(foundFactCount)s, infoset instance %(expectedFactCount)s" ), modelObject=(modelXbrl.modelDocument, infosetModelXbrl.modelDocument), foundFactCount=len(modelXbrl.factsInInstance), expectedFactCount=len(infosetModelXbrl.factsInInstance)) else: for i, instFact in enumerate(modelXbrl.facts): infosetFact = None for fact in infosetFacts[instFact.qname]: if fact.isTuple and fact.isDuplicateOf(instFact, deemP0Equal=True): infosetFact = fact break elif fact.isItem and fact.isVEqualTo(instFact, deemP0Equal=True): infosetFact = fact break if infosetFact is None: # takes precision/decimals into account if fact is not None: fact.isVEqualTo(instFact, deemP0Equal=True) modelXbrl.error( "arelle:infosetTest", _("Fact %(factNumber)s mismatch %(concept)s"), modelObject=instFact, factNumber=(i + 1), concept=instFact.qname) else: ptvPeriodType = infosetFact.get( "{http://www.xbrl.org/2003/ptv}periodType") ptvBalance = infosetFact.get( "{http://www.xbrl.org/2003/ptv}balance") ptvDecimals = infosetFact.get( "{http://www.xbrl.org/2003/ptv}decimals") ptvPrecision = infosetFact.get( "{http://www.xbrl.org/2003/ptv}precision") if ptvPeriodType and ptvPeriodType != instFact.concept.periodType: modelXbrl.error( "arelle:infosetTest", _("Fact %(factNumber)s periodType mismatch %(concept)s expected %(expectedPeriodType)s found %(foundPeriodType)s" ), modelObject=(instFact, infosetFact), factNumber=(i + 1), concept=instFact.qname, expectedPeriodType=ptvPeriodType, foundPeriodType=instFact.concept.periodType) if ptvBalance and ptvBalance != instFact.concept.balance: modelXbrl.error( "arelle:infosetTest", _("Fact %(factNumber)s balance mismatch %(concept)s expected %(expectedBalance)s found %(foundBalance)s" ), modelObject=(instFact, infosetFact), factNumber=(i + 1), concept=instFact.qname, expectedBalance=ptvBalance, foundBalance=instFact.concept.balance) if ptvDecimals and ptvDecimals != str( inferredDecimals(fact)): modelXbrl.error( "arelle:infosetTest", _("Fact %(factNumber)s inferred decimals mismatch %(concept)s expected %(expectedDecimals)s found %(inferredDecimals)s" ), modelObject=(instFact, infosetFact), factNumber=(i + 1), concept=instFact.qname, expectedDecimals=ptvDecimals, inferredDecimals=str(inferredDecimals(fact))) if ptvPrecision and ptvPrecision != str( inferredPrecision(fact)): modelXbrl.error( "arelle:infosetTest", _("Fact %(factNumber)s inferred precision mismatch %(concept)s expected %(expectedPrecision)s found %(inferredPrecision)s" ), modelObject=(instFact, infosetFact), factNumber=(i + 1), concept=instFact.qname, expectedPrecisions=ptvPrecision, inferredPrecision=str(inferredPrecision(fact))) elif infoset.type == Type.ARCSINFOSET: # compare arcs for arcElt in XmlUtil.children(infoset.xmlRootElement, "http://www.xbrl.org/2003/ptv", "arc"): linkType = arcElt.get("linkType") arcRole = arcElt.get("arcRole") extRole = arcElt.get("extRole") fromObj = resolvePath(modelXbrl, arcElt.get("fromPath")) if fromObj is None: modelXbrl.error("arelle:infosetTest", _("Arc fromPath not found: %(fromPath)s"), modelObject=arcElt, fromPath=arcElt.get("fromPath")) continue if linkType in ("label", "reference"): labelLang = arcElt.get("labelLang") resRole = arcElt.get("resRole") if linkType == "label": expectedLabel = XmlUtil.text(arcElt) foundLabel = fromObj.label(preferredLabel=resRole, fallbackToQname=False, lang=None, strip=True, linkrole=extRole) if foundLabel != expectedLabel: modelXbrl.error( "arelle:infosetTest", _("Label expected='%(expectedLabel)s', found='%(foundLabel)s'" ), modelObject=arcElt, expectedLabel=expectedLabel, foundLabel=foundLabel) continue elif linkType == "reference": expectedRef = XmlUtil.innerText(arcElt) referenceFound = False for refrel in modelXbrl.relationshipSet( XbrlConst.conceptReference, extRole).fromModelObject(fromObj): ref = refrel.toModelObject if resRole == ref.role: foundRef = XmlUtil.innerText(ref) if foundRef != expectedRef: modelXbrl.error( "arelle:infosetTest", _("Reference inner text expected='%(expectedRef)s, found='%(foundRef)s'" ), modelObject=arcElt, expectedRef=expectedRef, foundRef=foundRef) referenceFound = True break if referenceFound: continue modelXbrl.error( "arelle:infosetTest", _("%(linkType)s not found containing '%(text)s' linkRole %(linkRole)s" ), modelObject=arcElt, linkType=linkType.title(), text=XmlUtil.innerText(arcElt), linkRole=extRole) else: toObj = resolvePath(modelXbrl, arcElt.get("toPath")) if toObj is None: modelXbrl.error("arelle:infosetTest", _("Arc toPath not found: %(toPath)s"), modelObject=arcElt, toPath=arcElt.get("toPath")) continue weight = arcElt.get("weight") if weight is not None: weight = float(weight) order = arcElt.get("order") if order is not None: order = float(order) preferredLabel = arcElt.get("preferredLabel") found = False for rel in modelXbrl.relationshipSet( arcRole, extRole).fromModelObject(fromObj): if (rel.toModelObject == toObj and (weight is None or rel.weight == weight) and (order is None or rel.order == order)): found = True if not found: modelXbrl.error( "arelle:infosetTest", _("Arc not found: from %(fromPath)s, to %(toPath)s, role %(arcRole)s, linkRole $(extRole)s" ), modelObject=arcElt, fromPath=arcElt.get("fromPath"), toPath=arcElt.get("toPath"), arcRole=arcRole, linkRole=extRole) continue # validate dimensions of each fact factElts = XmlUtil.children(modelXbrl.modelDocument.xmlRootElement, None, "*") for itemElt in XmlUtil.children(infoset.xmlRootElement, None, "item"): try: qnElt = XmlUtil.child(itemElt, None, "qnElement") factQname = qname(qnElt, XmlUtil.text(qnElt)) sPointer = int(XmlUtil.child(itemElt, None, "sPointer").text) factElt = factElts[sPointer - 1] # 1-based xpath indexing if factElt.qname != factQname: modelXbrl.error( "arelle:infosetTest", _("Fact %(sPointer)s mismatch Qname, expected %(qnElt)s, observed %(factQname)s" ), modelObject=itemElt, sPointer=sPointer, qnElt=factQname, factQname=factElt.qname) elif not factElt.isItem or factElt.context is None: modelXbrl.error( "arelle:infosetTest", _("Fact %(sPointer)s has no context: %(qnElt)s"), modelObject=(itemElt, factElt), sPointer=sPointer, qnElt=factQname) else: context = factElt.context memberElts = XmlUtil.children(itemElt, None, "member") numNonDefaults = 0 for memberElt in memberElts: dimElt = XmlUtil.child(memberElt, None, "qnDimension") qnDim = qname(dimElt, XmlUtil.text(dimElt)) isDefault = XmlUtil.text( XmlUtil.child(memberElt, None, "bDefaulted")) == "true" if not isDefault: numNonDefaults += 1 if not ( (qnDim in context.qnameDims and not isDefault) or (qnDim in factElt.modelXbrl.qnameDimensionDefaults and isDefault)): modelXbrl.error( "arelle:infosetTest", _("Fact %(sPointer)s (qnElt)s dimension mismatch %(qnDim)s" ), modelObject=(itemElt, factElt, context), sPointer=sPointer, qnElt=factQname, qnDim=qnDim) if numNonDefaults != len(context.qnameDims): modelXbrl.error( "arelle:infosetTest", _("Fact %(sPointer)s (qnElt)s dimensions count mismatch" ), modelObject=(itemElt, factElt, context), sPointer=sPointer, qnElt=factQname) except (IndexError, ValueError, AttributeError) as err: modelXbrl.error( "arelle:infosetTest", _("Invalid entity fact dimensions infoset sPointer: %(test)s, error details: %(error)s" ), modelObject=itemElt, test=XmlUtil.innerTextList(itemElt), error=str(err))
def scenario(self): """(ModelObject) -- xbrli:scenario element""" return XmlUtil.child(self, XbrlConst.xbrli, "scenario")
def customAttributeQname(self, eventName): custAttrElt = XmlUtil.child(self, None, eventName) # will be vercd or verce if custAttrElt is not None and custAttrElt.get("name"): return qname(custAttrElt, custAttrElt.get("name")) return None
def fractionValue(self): return (XmlUtil.text(XmlUtil.child(self, None, "numerator")), XmlUtil.text(XmlUtil.child(self, None, "denominator")))
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 fractionValue(self): """( (str,str) ) -- (text value of numerator, text value of denominator)""" return (XmlUtil.text(XmlUtil.child(self, None, "numerator")), XmlUtil.text(XmlUtil.child(self, None, "denominator")))
def scenario(self): return XmlUtil.child(self, XbrlConst.xbrli, "scenario")
def toConceptQname(self): toConcept = XmlUtil.child(self.element, XbrlConst.vercb, "toConcept") if toConcept and toConcept.hasAttribute("name"): return qname(toConcept, toConcept.getAttribute("name")) else: return None
def period(self): try: return self._period except AttributeError: self._period = XmlUtil.child(self, XbrlConst.xbrli, "period") return self._period
def fromConceptQname(self): fromConcept = XmlUtil.child(self, None, "fromConcept") # can be vercu or vercb, schema validation will assure right elements if fromConcept is not None and fromConcept.get("name"): return qname(fromConcept, fromConcept.get("name")) else: return None
def segment(self): """(ModelObject) -- xbrli:segment element""" return XmlUtil.child(self.entity, XbrlConst.xbrli, "segment")
def __hash__(self): if self.isExplicit: return hash( (self.dimensionQname, self.memberQname) ) else: # need XPath equal so that QNames aren't lexically compared (for fact and context equality in comparing formula results) return hash( (self.dimensionQname, XbrlUtil.equalityHash(XmlUtil.child(self), equalMode=XbrlUtil.XPATH_EQ)) )
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 segment(self): return XmlUtil.child(self.entity, XbrlConst.xbrli, "segment")