def compareDTSes(self, versReportFile): from arelle.ModelVersReport import ModelVersReport if len(self.loadedModelXbrls) == 2: from arelle.ModelDocument import Type modelVersReport = self.create( newDocumentType=Type.VERSIONINGREPORT, url=versReportFile, createModelDocument=False) ModelVersReport(modelVersReport).diffDTSes( versReportFile, self.loadedModelXbrls[0], self.loadedModelXbrls[1]) return modelVersReport
def compareDTSes(self, versReportFile, writeReportFile=True): from arelle.ModelVersReport import ModelVersReport if len(self.loadedModelXbrls) >= 2: fromDTS = self.loadedModelXbrls[-2] toDTS = self.loadedModelXbrls[-1] from arelle.ModelDocument import Type modelVersReport = self.create( newDocumentType=Type.VERSIONINGREPORT, url=versReportFile, createModelDocument=False) ModelVersReport(modelVersReport).diffDTSes(versReportFile, fromDTS, toDTS) return modelVersReport return None
def compareDTSes(self, versReportFile, writeReportFile=True): """Compare two most recently loaded DTSes, saving versioning report in to the file name provided. :param versReportFile: file name in which to save XBRL Versioning Report :type versReportFile: str :param writeReportFile: False to prevent writing XBRL Versioning Report file :type writeReportFile: bool """ from arelle.ModelVersReport import ModelVersReport if len(self.loadedModelXbrls) >= 2: fromDTS = self.loadedModelXbrls[-2] toDTS = self.loadedModelXbrls[-1] from arelle.ModelDocument import Type modelVersReport = self.create(newDocumentType=Type.VERSIONINGREPORT, url=versReportFile, createModelDocument=False) ModelVersReport(modelVersReport).diffDTSes(versReportFile, fromDTS, toDTS) return modelVersReport return None
def load(modelXbrl, uri, base=None, referringElement=None, isEntry=False, isDiscovered=False, isIncluded=None, namespace=None, reloadCache=False): if referringElement is None: # used for error messages referringElement = modelXbrl normalizedUri = modelXbrl.modelManager.cntlr.webCache.normalizeUrl(uri, base) if isEntry: modelXbrl.entryLoadingUrl = normalizedUri # for error loggiong during loading modelXbrl.uri = normalizedUri modelXbrl.uriDir = os.path.dirname(normalizedUri) for i in range(modelXbrl.modelManager.disclosureSystem.maxSubmissionSubdirectoryEntryNesting): modelXbrl.uriDir = os.path.dirname(modelXbrl.uriDir) if modelXbrl.modelManager.validateDisclosureSystem and \ not normalizedUri.startswith(modelXbrl.uriDir) and \ not modelXbrl.modelManager.disclosureSystem.hrefValid(normalizedUri): blocked = modelXbrl.modelManager.disclosureSystem.blockDisallowedReferences modelXbrl.error(("EFM.6.22.02", "GFM.1.1.3", "SBR.NL.2.1.0.06"), _("Prohibited file for filings %(blockedIndicator)s: %(url)s"), modelObject=referringElement, url=normalizedUri, blockedIndicator=_(" blocked") if blocked else "") if blocked: return None if normalizedUri in modelXbrl.modelManager.disclosureSystem.mappedFiles: mappedUri = modelXbrl.modelManager.disclosureSystem.mappedFiles[normalizedUri] else: # handle mapped paths mappedUri = normalizedUri for mapFrom, mapTo in modelXbrl.modelManager.disclosureSystem.mappedPaths: if normalizedUri.startswith(mapFrom): mappedUri = mapTo + normalizedUri[len(mapFrom):] break if isEntry: modelXbrl.entryLoadingUrl = mappedUri # for error loggiong during loading if modelXbrl.fileSource.isInArchive(mappedUri): filepath = mappedUri else: filepath = modelXbrl.modelManager.cntlr.webCache.getfilename(mappedUri, reload=reloadCache) if filepath: uri = modelXbrl.modelManager.cntlr.webCache.normalizeUrl(filepath) if filepath is None: # error such as HTTPerror is already logged modelXbrl.error("FileNotLoadable", _("File can not be loaded: %(fileName)s"), modelObject=referringElement, fileName=mappedUri) type = Type.Unknown return None modelDocument = modelXbrl.urlDocs.get(mappedUri) if modelDocument: return modelDocument # load XML and determine type of model document modelXbrl.modelManager.showStatus(_("parsing {0}").format(uri)) file = None try: if (modelXbrl.modelManager.validateDisclosureSystem and modelXbrl.modelManager.disclosureSystem.validateFileText): file, _encoding = ValidateFilingText.checkfile(modelXbrl,filepath) else: file, _encoding = modelXbrl.fileSource.file(filepath) _parser, _parserLookupName, _parserLookupClass = parser(modelXbrl,filepath) xmlDocument = etree.parse(file,parser=_parser,base_url=filepath) file.close() except (EnvironmentError, KeyError) as err: # missing zip file raises KeyError modelXbrl.error("IOerror", _("%(fileName)s: file error: %(error)s"), modelObject=referringElement, fileName=os.path.basename(uri), error=str(err)) type = Type.Unknown if file: file.close() return None except (etree.LxmlError, ValueError) as err: # ValueError raised on bad format of qnames, xmlns'es, or parameters modelXbrl.error("xmlSchema:syntax", _("%(error)s, %(fileName)s, %(sourceAction)s source element"), modelObject=referringElement, fileName=os.path.basename(uri), error=str(err), sourceAction=("including" if isIncluded else "importing")) type = Type.Unknown if file: file.close() return None # identify document #modelXbrl.modelManager.addToLog("discovery: {0}".format( # os.path.basename(uri))) modelXbrl.modelManager.showStatus(_("loading {0}").format(uri)) modelDocument = None rootNode = xmlDocument.getroot() if rootNode is not None: ln = rootNode.localName ns = rootNode.namespaceURI # type classification if ns == XbrlConst.xsd and ln == "schema": type = Type.SCHEMA elif ns == XbrlConst.link: if ln == "linkbase": type = Type.LINKBASE elif ln == "xbrl": type = Type.INSTANCE elif ns == XbrlConst.xbrli: if ln == "xbrl": type = Type.INSTANCE elif ns == XbrlConst.xhtml and \ (ln == "html" or ln == "xhtml"): type = Type.Unknown if XbrlConst.ixbrl in rootNode.nsmap.values(): type = Type.INLINEXBRL elif ln == "report" and ns == XbrlConst.ver: type = Type.VERSIONINGREPORT elif ln == "testcases" or ln == "documentation": type = Type.TESTCASESINDEX elif ln == "testcase": type = Type.TESTCASE elif ln == "registry" and ns == XbrlConst.registry: type = Type.REGISTRY elif ln == "rss": type = Type.RSSFEED else: type = Type.Unknown nestedInline = None for htmlElt in rootNode.iter(tag="{http://www.w3.org/1999/xhtml}html"): nestedInline = htmlElt break if nestedInline is None: for htmlElt in rootNode.iter(tag="{http://www.w3.org/1999/xhtml}xhtml"): nestedInline = htmlElt break if nestedInline is not None: if XbrlConst.ixbrl in nestedInline.nsmap.values(): type = Type.INLINEXBRL rootNode = nestedInline #create modelDocument object or subtype as identified if type == Type.VERSIONINGREPORT: from arelle.ModelVersReport import ModelVersReport modelDocument = ModelVersReport(modelXbrl, type, mappedUri, filepath, xmlDocument) elif type == Type.RSSFEED: from arelle.ModelRssObject import ModelRssObject modelDocument = ModelRssObject(modelXbrl, type, mappedUri, filepath, xmlDocument) else: modelDocument = ModelDocument(modelXbrl, type, mappedUri, filepath, xmlDocument) rootNode.init(modelDocument) modelDocument.parser = _parser # needed for XmlUtil addChild's makeelement modelDocument.parserLookupName = _parserLookupName modelDocument.parserLookupClass = _parserLookupClass modelDocument.xmlRootElement = rootNode modelDocument.schemaLocationElements.add(rootNode) modelDocument.documentEncoding = _encoding if isEntry or isDiscovered: modelDocument.inDTS = True # discovery (parsing) if type == Type.SCHEMA: modelDocument.schemaDiscover(rootNode, isIncluded, namespace) elif type == Type.LINKBASE: modelDocument.linkbaseDiscover(rootNode) elif type == Type.INSTANCE: modelDocument.instanceDiscover(rootNode) elif type == Type.INLINEXBRL: modelDocument.inlineXbrlDiscover(rootNode) elif type == Type.VERSIONINGREPORT: modelDocument.versioningReportDiscover(rootNode) elif type == Type.TESTCASESINDEX: modelDocument.testcasesIndexDiscover(xmlDocument) elif type == Type.TESTCASE: modelDocument.testcaseDiscover(rootNode) elif type == Type.REGISTRY: modelDocument.registryDiscover(rootNode) elif type == Type.VERSIONINGREPORT: modelDocument.versioningReportDiscover(rootNode) elif type == Type.RSSFEED: modelDocument.rssFeedDiscover(rootNode) return modelDocument
def load(modelXbrl, uri, base=None, isEntry=False, isIncluded=None, namespace=None, reloadCache=False): normalizedUri = modelXbrl.modelManager.cntlr.webCache.normalizeUrl(uri, base) if isEntry: modelXbrl.uri = normalizedUri modelXbrl.uriDir = os.path.dirname(normalizedUri) for i in range(modelXbrl.modelManager.disclosureSystem.maxSubmissionSubdirectoryEntryNesting): modelXbrl.uriDir = os.path.dirname(modelXbrl.uriDir) if modelXbrl.modelManager.validateDisclosureSystem and \ not normalizedUri.startswith(modelXbrl.uriDir) and \ not modelXbrl.modelManager.disclosureSystem.hrefValid(normalizedUri): blocked = modelXbrl.modelManager.disclosureSystem.blockDisallowedReferences modelXbrl.error( "Prohibited file for filings{1}: {0}".format(normalizedUri, _(" blocked") if blocked else ""), "err", "EFM.6.22.02", "GFM.1.1.3", "SBR.NL.2.1.0.06") if blocked: return None if normalizedUri in modelXbrl.modelManager.disclosureSystem.mappedFiles: mappedUri = modelXbrl.modelManager.disclosureSystem.mappedFiles[normalizedUri] else: # handle mapped paths mappedUri = normalizedUri for mapFrom, mapTo in modelXbrl.modelManager.disclosureSystem.mappedPaths: if normalizedUri.startswith(mapFrom): mappedUri = mapTo + normalizedUri[len(mapFrom):] break if modelXbrl.fileSource.isInArchive(mappedUri): filepath = mappedUri else: filepath = modelXbrl.modelManager.cntlr.webCache.getfilename(mappedUri, reload=reloadCache) if filepath: uri = modelXbrl.modelManager.cntlr.webCache.normalizeUrl(filepath) if filepath is None: # error such as HTTPerror is already logged modelXbrl.error( "File can not be loaded: {0}".format( mappedUri), "err", "FileNotLoadable") type = Type.Unknown return None modelDocument = modelXbrl.urlDocs.get(mappedUri) if modelDocument: return modelDocument # load XML and determine type of model document modelXbrl.modelManager.showStatus(_("parsing {0}").format(uri)) file = None try: if modelXbrl.modelManager.validateDisclosureSystem: file = ValidateFilingText.checkfile(modelXbrl,filepath) else: file = modelXbrl.fileSource.file(filepath) xmlDocument = xml.dom.minidom.parse(file) file.close() except EnvironmentError as err: modelXbrl.error( "{0}: file error: {1}".format( os.path.basename(uri), err), "err", "IOerror") type = Type.Unknown if file: file.close() return None except (xml.parsers.expat.ExpatError, xml.dom.DOMException, ValueError) as err: # ValueError raised on bad format of qnames, xmlns'es, or parameters modelXbrl.error( "{0}: import error: {1}".format( os.path.basename(uri), err), "err", "XMLsyntax") type = Type.Unknown if file: file.close() return None # identify document #modelXbrl.modelManager.addToLog("discovery: {0}".format( # os.path.basename(uri))) modelXbrl.modelManager.showStatus(_("loading {0}").format(uri)) modelDocument = None for rootNode in xmlDocument.childNodes: if rootNode.nodeType == 1: #element ln = rootNode.localName ns = rootNode.namespaceURI # type classification if ns == XbrlConst.xsd and ln == "schema": type = Type.SCHEMA elif ns == XbrlConst.link: if ln == "linkbase": type = Type.LINKBASE elif ln == "xbrl": type = Type.INSTANCE elif ns == XbrlConst.xbrli: if ln == "xbrl": type = Type.INSTANCE elif ns == XbrlConst.xhtml and \ ln == "html" or ln == "xhtml": type = Type.Unknown for i in range(len(rootNode.attributes)): if rootNode.attributes.item(i).value == XbrlConst.ixbrl: type = Type.INLINEXBRL break XmlUtil.markIdAttributes(rootNode) # required for minidom searchability elif ln == "report" and ns == XbrlConst.ver: type = Type.VERSIONINGREPORT elif ln == "testcases" or ln == "documentation": type = Type.TESTCASESINDEX elif ln == "testcase": type = Type.TESTCASE elif ln == "registry" and ns == XbrlConst.registry: type = Type.REGISTRY elif ln == "rss": type = Type.RSSFEED else: type = Type.Unknown nestedInline = XmlUtil.descendant(rootNode, XbrlConst.xhtml, ("html", "xhtml")) if nestedInline: for i in range(len(nestedInline.attributes)): if nestedInline.attributes.item(i).value == XbrlConst.ixbrl: type = Type.INLINEXBRL rootNode = nestedInline break XmlUtil.markIdAttributes(rootNode) # required for minidom searchability #create modelDocument object or subtype as identified if type == Type.VERSIONINGREPORT: from arelle.ModelVersReport import ModelVersReport modelDocument = ModelVersReport(modelXbrl, type, mappedUri, filepath, xmlDocument) elif type == Type.RSSFEED: from arelle.ModelRssObject import ModelRssObject modelDocument = ModelRssObject(modelXbrl, type, mappedUri, filepath, xmlDocument) else: modelDocument = ModelDocument(modelXbrl, type, mappedUri, filepath, xmlDocument) modelDocument.xmlRootElement = rootNode modelDocument.schemaLocationElements.add(rootNode) if isEntry: modelDocument.inDTS = True # discovery (parsing) if type == Type.SCHEMA: modelDocument.schemaDiscover(rootNode, isIncluded, namespace) elif type == Type.LINKBASE: modelDocument.linkbaseDiscover(rootNode) elif type == Type.INSTANCE: modelDocument.instanceDiscover(rootNode) elif type == Type.INLINEXBRL: modelDocument.inlineXbrlDiscover(rootNode) elif type == Type.VERSIONINGREPORT: modelDocument.versioningReportDiscover(rootNode) elif type == Type.TESTCASESINDEX: modelDocument.testcasesIndexDiscover(xmlDocument) elif type == Type.TESTCASE: modelDocument.testcaseDiscover(rootNode) elif type == Type.REGISTRY: modelDocument.registryDiscover(rootNode) elif type == Type.VERSIONINGREPORT: modelDocument.versioningReportDiscover(rootNode) elif type == Type.RSSFEED: modelDocument.rssFeedDiscover(rootNode) break return modelDocument
def load(modelXbrl, uri, base=None, referringElement=None, isEntry=False, isDiscovered=False, isIncluded=None, namespace=None, reloadCache=False): if referringElement is None: # used for error messages referringElement = modelXbrl normalizedUri = modelXbrl.modelManager.cntlr.webCache.normalizeUrl( uri, base) if isEntry: modelXbrl.entryLoadingUrl = normalizedUri # for error loggiong during loading modelXbrl.uri = normalizedUri modelXbrl.uriDir = os.path.dirname(normalizedUri) for i in range(modelXbrl.modelManager.disclosureSystem. maxSubmissionSubdirectoryEntryNesting): modelXbrl.uriDir = os.path.dirname(modelXbrl.uriDir) if modelXbrl.modelManager.validateDisclosureSystem and \ not normalizedUri.startswith(modelXbrl.uriDir) and \ not modelXbrl.modelManager.disclosureSystem.hrefValid(normalizedUri): blocked = modelXbrl.modelManager.disclosureSystem.blockDisallowedReferences modelXbrl.error( ("EFM.6.22.02", "GFM.1.1.3", "SBR.NL.2.1.0.06" if normalizedUri.startswith("http") else "SBR.NL.2.2.0.17"), _("Prohibited file for filings %(blockedIndicator)s: %(url)s"), modelObject=referringElement, url=normalizedUri, blockedIndicator=_(" blocked") if blocked else "") if blocked: return None if normalizedUri in modelXbrl.modelManager.disclosureSystem.mappedFiles: mappedUri = modelXbrl.modelManager.disclosureSystem.mappedFiles[ normalizedUri] else: # handle mapped paths mappedUri = normalizedUri for mapFrom, mapTo in modelXbrl.modelManager.disclosureSystem.mappedPaths: if normalizedUri.startswith(mapFrom): mappedUri = mapTo + normalizedUri[len(mapFrom):] break if isEntry: modelXbrl.entryLoadingUrl = mappedUri # for error loggiong during loading if modelXbrl.fileSource.isInArchive(mappedUri): filepath = mappedUri else: filepath = modelXbrl.modelManager.cntlr.webCache.getfilename( mappedUri, reload=reloadCache) if filepath: uri = modelXbrl.modelManager.cntlr.webCache.normalizeUrl(filepath) if filepath is None: # error such as HTTPerror is already logged modelXbrl.error("FileNotLoadable", _("File can not be loaded: %(fileName)s"), modelObject=referringElement, fileName=mappedUri) return None modelDocument = modelXbrl.urlDocs.get(mappedUri) if modelDocument: return modelDocument # load XML and determine type of model document modelXbrl.modelManager.showStatus(_("parsing {0}").format(uri)) file = None try: if (modelXbrl.modelManager.validateDisclosureSystem and modelXbrl.modelManager.disclosureSystem.validateFileText): file, _encoding = ValidateFilingText.checkfile(modelXbrl, filepath) else: file, _encoding = modelXbrl.fileSource.file(filepath) _parser, _parserLookupName, _parserLookupClass = parser( modelXbrl, filepath) xmlDocument = etree.parse(file, parser=_parser, base_url=filepath) file.close() except (EnvironmentError, KeyError) as err: # missing zip file raises KeyError if file: file.close() # retry in case of well known schema locations if not isIncluded and namespace and namespace in XbrlConst.standardNamespaceSchemaLocations and uri != XbrlConst.standardNamespaceSchemaLocations[ namespace]: return load(modelXbrl, XbrlConst.standardNamespaceSchemaLocations[namespace], base, referringElement, isEntry, isDiscovered, isIncluded, namespace, reloadCache) modelXbrl.error("IOerror", _("%(fileName)s: file error: %(error)s"), modelObject=referringElement, fileName=os.path.basename(uri), error=str(err)) return None except ( etree.LxmlError, ValueError ) as err: # ValueError raised on bad format of qnames, xmlns'es, or parameters if file: file.close() if not isEntry and str( err) == "Start tag expected, '<' not found, line 1, column 1": return ModelDocument(modelXbrl, Type.UnknownNonXML, mappedUri, filepath, None) else: modelXbrl.error( "xmlSchema:syntax", _("%(error)s, %(fileName)s, %(sourceAction)s source element"), modelObject=referringElement, fileName=os.path.basename(uri), error=str(err), sourceAction=("including" if isIncluded else "importing")) return None # identify document #modelXbrl.modelManager.addToLog("discovery: {0}".format( # os.path.basename(uri))) modelXbrl.modelManager.showStatus(_("loading {0}").format(uri)) modelDocument = None rootNode = xmlDocument.getroot() if rootNode is not None: ln = rootNode.localName ns = rootNode.namespaceURI # type classification if ns == XbrlConst.xsd and ln == "schema": type = Type.SCHEMA elif ns == XbrlConst.link: if ln == "linkbase": type = Type.LINKBASE elif ln == "xbrl": type = Type.INSTANCE elif ns == XbrlConst.xbrli: if ln == "xbrl": type = Type.INSTANCE elif ns == XbrlConst.xhtml and \ (ln == "html" or ln == "xhtml"): type = Type.UnknownXML if XbrlConst.ixbrl in rootNode.nsmap.values(): type = Type.INLINEXBRL elif ln == "report" and ns == XbrlConst.ver: type = Type.VERSIONINGREPORT elif ln == "testcases" or ln == "documentation": type = Type.TESTCASESINDEX elif ln == "testcase": type = Type.TESTCASE elif ln == "registry" and ns == XbrlConst.registry: type = Type.REGISTRY elif ln == "rss": type = Type.RSSFEED elif ln == "ptvl": type = Type.ARCSINFOSET elif ln == "facts": type = Type.FACTDIMSINFOSET else: type = Type.UnknownXML nestedInline = None for htmlElt in rootNode.iter( tag="{http://www.w3.org/1999/xhtml}html"): nestedInline = htmlElt break if nestedInline is None: for htmlElt in rootNode.iter( tag="{http://www.w3.org/1999/xhtml}xhtml"): nestedInline = htmlElt break if nestedInline is not None: if XbrlConst.ixbrl in nestedInline.nsmap.values(): type = Type.INLINEXBRL rootNode = nestedInline #create modelDocument object or subtype as identified if type == Type.VERSIONINGREPORT: from arelle.ModelVersReport import ModelVersReport modelDocument = ModelVersReport(modelXbrl, type, mappedUri, filepath, xmlDocument) elif type == Type.RSSFEED: from arelle.ModelRssObject import ModelRssObject modelDocument = ModelRssObject(modelXbrl, type, mappedUri, filepath, xmlDocument) else: modelDocument = ModelDocument(modelXbrl, type, mappedUri, filepath, xmlDocument) rootNode.init(modelDocument) modelDocument.parser = _parser # needed for XmlUtil addChild's makeelement modelDocument.parserLookupName = _parserLookupName modelDocument.parserLookupClass = _parserLookupClass modelDocument.xmlRootElement = rootNode modelDocument.schemaLocationElements.add(rootNode) modelDocument.documentEncoding = _encoding if isEntry or isDiscovered: modelDocument.inDTS = True # discovery (parsing) if type == Type.SCHEMA: modelDocument.schemaDiscover(rootNode, isIncluded, namespace) elif type == Type.LINKBASE: modelDocument.linkbaseDiscover(rootNode) elif type == Type.INSTANCE: modelDocument.instanceDiscover(rootNode) elif type == Type.INLINEXBRL: modelDocument.inlineXbrlDiscover(rootNode) elif type == Type.VERSIONINGREPORT: modelDocument.versioningReportDiscover(rootNode) elif type == Type.TESTCASESINDEX: modelDocument.testcasesIndexDiscover(xmlDocument) elif type == Type.TESTCASE: modelDocument.testcaseDiscover(rootNode) elif type == Type.REGISTRY: modelDocument.registryDiscover(rootNode) elif type == Type.VERSIONINGREPORT: modelDocument.versioningReportDiscover(rootNode) elif type == Type.RSSFEED: modelDocument.rssFeedDiscover(rootNode) return modelDocument
def load(modelXbrl, uri, base=None, isEntry=False, isIncluded=None, namespace=None, reloadCache=False): normalizedUri = modelXbrl.modelManager.cntlr.webCache.normalizeUrl( uri, base) if isEntry: modelXbrl.uri = normalizedUri modelXbrl.uriDir = os.path.dirname(normalizedUri) for i in range(modelXbrl.modelManager.disclosureSystem. maxSubmissionSubdirectoryEntryNesting): modelXbrl.uriDir = os.path.dirname(modelXbrl.uriDir) if modelXbrl.modelManager.validateDisclosureSystem and \ not normalizedUri.startswith(modelXbrl.uriDir) and \ not modelXbrl.modelManager.disclosureSystem.hrefValid(normalizedUri): blocked = modelXbrl.modelManager.disclosureSystem.blockDisallowedReferences modelXbrl.error( "Prohibited file for filings{1}: {0}".format( normalizedUri, _(" blocked") if blocked else ""), "err", "EFM.6.22.02", "GFM.1.1.3", "SBR.NL.2.1.0.06") if blocked: return None if normalizedUri in modelXbrl.modelManager.disclosureSystem.mappedFiles: mappedUri = modelXbrl.modelManager.disclosureSystem.mappedFiles[ normalizedUri] else: # handle mapped paths mappedUri = normalizedUri for mapFrom, mapTo in modelXbrl.modelManager.disclosureSystem.mappedPaths: if normalizedUri.startswith(mapFrom): mappedUri = mapTo + normalizedUri[len(mapFrom):] break if modelXbrl.fileSource.isInArchive(mappedUri): filepath = mappedUri else: filepath = modelXbrl.modelManager.cntlr.webCache.getfilename( mappedUri, reload=reloadCache) if filepath: uri = modelXbrl.modelManager.cntlr.webCache.normalizeUrl(filepath) if filepath is None: # error such as HTTPerror is already logged modelXbrl.error("File can not be loaded: {0}".format(mappedUri), "err", "FileNotLoadable") type = Type.Unknown return None modelDocument = modelXbrl.urlDocs.get(mappedUri) if modelDocument: return modelDocument # load XML and determine type of model document modelXbrl.modelManager.showStatus(_("parsing {0}").format(uri)) file = None try: if modelXbrl.modelManager.validateDisclosureSystem: file = ValidateFilingText.checkfile(modelXbrl, filepath) else: file = modelXbrl.fileSource.file(filepath) xmlDocument = xml.dom.minidom.parse(file) file.close() except EnvironmentError as err: modelXbrl.error( "{0}: file error: {1}".format(os.path.basename(uri), err), "err", "IOerror") type = Type.Unknown if file: file.close() return None except ( xml.parsers.expat.ExpatError, xml.dom.DOMException, ValueError ) as err: # ValueError raised on bad format of qnames, xmlns'es, or parameters modelXbrl.error( "{0}: import error: {1}".format(os.path.basename(uri), err), "err", "XMLsyntax") type = Type.Unknown if file: file.close() return None # identify document #modelXbrl.modelManager.addToLog("discovery: {0}".format( # os.path.basename(uri))) modelXbrl.modelManager.showStatus(_("loading {0}").format(uri)) modelDocument = None for rootNode in xmlDocument.childNodes: if rootNode.nodeType == 1: #element ln = rootNode.localName ns = rootNode.namespaceURI # type classification if ns == XbrlConst.xsd and ln == "schema": type = Type.SCHEMA elif ns == XbrlConst.link: if ln == "linkbase": type = Type.LINKBASE elif ln == "xbrl": type = Type.INSTANCE elif ns == XbrlConst.xbrli: if ln == "xbrl": type = Type.INSTANCE elif ns == XbrlConst.xhtml and \ ln == "html" or ln == "xhtml": type = Type.Unknown for i in range(len(rootNode.attributes)): if rootNode.attributes.item(i).value == XbrlConst.ixbrl: type = Type.INLINEXBRL break XmlUtil.markIdAttributes( rootNode) # required for minidom searchability elif ln == "report" and ns == XbrlConst.ver: type = Type.VERSIONINGREPORT elif ln == "testcases" or ln == "documentation": type = Type.TESTCASESINDEX elif ln == "testcase": type = Type.TESTCASE elif ln == "registry" and ns == XbrlConst.registry: type = Type.REGISTRY elif ln == "rss": type = Type.RSSFEED else: type = Type.Unknown nestedInline = XmlUtil.descendant(rootNode, XbrlConst.xhtml, ("html", "xhtml")) if nestedInline: for i in range(len(nestedInline.attributes)): if nestedInline.attributes.item( i).value == XbrlConst.ixbrl: type = Type.INLINEXBRL rootNode = nestedInline break XmlUtil.markIdAttributes( rootNode) # required for minidom searchability #create modelDocument object or subtype as identified if type == Type.VERSIONINGREPORT: from arelle.ModelVersReport import ModelVersReport modelDocument = ModelVersReport(modelXbrl, type, mappedUri, filepath, xmlDocument) elif type == Type.RSSFEED: from arelle.ModelRssObject import ModelRssObject modelDocument = ModelRssObject(modelXbrl, type, mappedUri, filepath, xmlDocument) else: modelDocument = ModelDocument(modelXbrl, type, mappedUri, filepath, xmlDocument) modelDocument.xmlRootElement = rootNode modelDocument.schemaLocationElements.add(rootNode) if isEntry: modelDocument.inDTS = True # discovery (parsing) if type == Type.SCHEMA: modelDocument.schemaDiscover(rootNode, isIncluded, namespace) elif type == Type.LINKBASE: modelDocument.linkbaseDiscover(rootNode) elif type == Type.INSTANCE: modelDocument.instanceDiscover(rootNode) elif type == Type.INLINEXBRL: modelDocument.inlineXbrlDiscover(rootNode) elif type == Type.VERSIONINGREPORT: modelDocument.versioningReportDiscover(rootNode) elif type == Type.TESTCASESINDEX: modelDocument.testcasesIndexDiscover(xmlDocument) elif type == Type.TESTCASE: modelDocument.testcaseDiscover(rootNode) elif type == Type.REGISTRY: modelDocument.registryDiscover(rootNode) elif type == Type.VERSIONINGREPORT: modelDocument.versioningReportDiscover(rootNode) elif type == Type.RSSFEED: modelDocument.rssFeedDiscover(rootNode) break return modelDocument