def close(self, noWrite=False): if self.type == CSV: if not isinstance(self.outfile, FileNamedStringIO): self.csvFile.close() elif not noWrite: fileType = TYPENAMES[self.type] try: from arelle import XmlUtil if isinstance(self.outfile, FileNamedStringIO): fh = self.outfile else: fh = open(self.outfile, "w", encoding="utf-8") if self.type == JSON: fh.write(json.dumps(self.jsonObject, ensure_ascii=False)) else: XmlUtil.writexml(fh, self.xmlDoc, encoding="utf-8", xmlcharrefreplace= (self.type == HTML) ) if not isinstance(self.outfile, FileNamedStringIO): fh.close() self.modelXbrl.info("info", _("Saved output %(type)s to %(file)s"), file=self.outfile, type=fileType) except (IOError, EnvironmentError) as err: self.modelXbrl.exception("arelle:htmlIOError", _("Failed to save output %(type)s to %(file)s: \s%(error)s"), file=self.outfile, type=fileType, error=err) self.modelXbrl = None if self.type == HTML: self.tblElt = None elif self.type == XML: self.docEltLevels = None self.__dict__.clear() # dereference everything after closing document
def generateInstanceInfoset(dts, instanceInfosetFile): if dts.fileSource.isArchive: return import os, io from arelle import XmlUtil, XbrlConst from arelle.ValidateXbrlCalcs import inferredPrecision, inferredDecimals XmlUtil.setXmlns(dts.modelDocument, "ptv", "http://www.xbrl.org/2003/ptv") numFacts = 0 for fact in dts.facts: try: if fact.concept.periodType: fact.set("{http://www.xbrl.org/2003/ptv}periodType", fact.concept.periodType) if fact.concept.balance: fact.set("{http://www.xbrl.org/2003/ptv}balance", fact.concept.balance) if fact.isNumeric and not fact.isNil: fact.set("{http://www.xbrl.org/2003/ptv}decimals", str(inferredDecimals(fact))) fact.set("{http://www.xbrl.org/2003/ptv}precision", str(inferredPrecision(fact))) numFacts += 1 except Exception as err: dts.error("saveInfoset.exception", _("Facts exception %(fact)s %(value)s %(error)s."), modelObject=fact, fact=fact.qname, value=fact.effectiveValue, error = err) fh = open(instanceInfosetFile, "w", encoding="utf-8") XmlUtil.writexml(fh, dts.modelDocument.xmlDocument, encoding="utf-8") fh.close() dts.info("info:saveInstanceInfoset", _("Instance infoset of %(entryFile)s has %(numberOfFacts)s facts in infoset file %(infosetOutputFile)s."), modelObject=dts, entryFile=dts.uri, numberOfFacts=numFacts, infosetOutputFile=instanceInfosetFile)
def saveInstance(self, overrideFilepath=None): """Saves current instance document file. :param overrideFilepath: specify to override saving in instance's modelDocument.filepath """ with open( (overrideFilepath or self.modelDocument.filepath), "w", encoding='utf-8') as fh: XmlUtil.writexml(fh, self.modelDocument.xmlDocument, encoding="utf-8")
def close(self, noWrite=False): if self.type == CSV: if not isinstance(self.outfile, FileNamedStringIO): self.csvFile.close() elif self.type == XLSX: # add filtering self.xlsxWs.auto_filter.ref = 'A1:{}{}'.format(utils.get_column_letter(self.xlsxWs.max_column), len(self.xlsxWs['A'])) self.xlsxWb.save(self.outfile) elif self.type != NOOUT and not noWrite: fileType = TYPENAMES[self.type] try: from arelle import XmlUtil if isinstance(self.outfile, FileNamedStringIO): fh = self.outfile else: fh = open(self.outfile, "w", encoding="utf-8") if self.type == JSON: fh.write(json.dumps(self.jsonObject, ensure_ascii=False)) else: XmlUtil.writexml(fh, self.xmlDoc, encoding="utf-8", xmlcharrefreplace= (self.type == HTML) ) if not isinstance(self.outfile, FileNamedStringIO): fh.close() self.modelXbrl.info("info", _("Saved output %(type)s to %(file)s"), file=self.outfile, type=fileType) except (IOError, EnvironmentError) as err: self.modelXbrl.exception("arelle:htmlIOError", _("Failed to save output %(type)s to %(file)s: %(error)s"), file=self.outfile, type=fileType, error=err) self.modelXbrl = None if self.type == HTML: self.tblElt = None elif self.type == XML: self.docEltLevels = None self.__dict__.clear() # dereference everything after closing document
def generateInfoset(dts, infosetFile): if dts.fileSource.isArchive: return import os, io from arelle import XmlUtil, XbrlConst from arelle.ValidateXbrlCalcs import inferredPrecision, inferredDecimals XmlUtil.setXmlns(dts.modelDocument, "ptv", "http://www.xbrl.org/2003/ptv") numFacts = 0 for fact in dts.facts: try: if fact.concept.periodType: fact.set("{http://www.xbrl.org/2003/ptv}periodType", fact.concept.periodType) if fact.concept.balance: fact.set("{http://www.xbrl.org/2003/ptv}balance", fact.concept.balance) if fact.isNumeric and not fact.isNil: fact.set("{http://www.xbrl.org/2003/ptv}decimals", str(inferredDecimals(fact))) fact.set("{http://www.xbrl.org/2003/ptv}precision", str(inferredPrecision(fact))) numFacts += 1 except Exception as err: dts.error("saveInfoset.exception", _("Facts exception %(fact)s %(value)s %(error)s."), modelObject=fact, fact=fact.qname, value=fact.effectiveValue, error = err) fh = open(infosetFile, "w", encoding="utf-8") XmlUtil.writexml(fh, dts.modelDocument.xmlDocument, encoding="utf-8") fh.close() dts.info("info:saveInfoset", _("Infoset of %(entryFile)s has %(numberOfFacts)s facts in infoset file %(infosetOutputFile)s."), modelObject=dts, entryFile=dts.uri, numberOfFacts=numFacts, infosetOutputFile=infosetFile)
def close(self): if self.type == CSV: if not isinstance(self.outfile, FileNamedStringIO): self.csvFile.close() self.modelXbrl = None else: fileType = TYPENAMES[self.type] try: from arelle import XmlUtil if isinstance(self.outfile, FileNamedStringIO): fh = self.outfile else: fh = open(self.outfile, "w") if self.type == JSON: fh.write(json.dumps(self.jsonObject)) else: XmlUtil.writexml(fh, self.xmlDoc, encoding="utf-8") if not isinstance(self.outfile, FileNamedStringIO): fh.close() self.modelXbrl.info("info", _("Saved output %(type)s to %(file)s"), file=self.outfile, type=fileType) except (IOError, EnvironmentError) as err: self.modelXbrl.exception("arelle:htmlIOError", _("Failed to save output %(type)s to %(file)s: \s%(error)s"), file=self.outfile, type=fileType, error=err) self.modelXbrl = None if self.type == HTML: self.tblElt = None elif self.type == XML: self.docEltLevels = None self.__dict__.clear() # dereference everything after closing document
def write(self): try: from arelle import XmlUtil with open(self.outfile, "w") as fh: XmlUtil.writexml(fh, self.htmlDoc, encoding="utf-8") self.modelXbrl.info("info", _("Saved output html to %(file)s"), file=self.outfile) except (IOError, EnvironmentError) as err: self.modelXbrl.exception("arelle:htmlIOError", _("Failed to save output html to %(file)s: \s%(error)s"), file=self.outfile, error=err)
def generateCHComponent(dts, componentFile): if dts.fileSource.isArchive: return import os, io from arelle import XmlUtil, XbrlConst file = io.StringIO(''' <nsmap> <Component/> </nsmap> ''') from arelle.ModelObjectFactory import parser parser, parserLookupName, parserLookupClass = parser(dts, None) xmlDocument = etree.parse(file, parser=parser, base_url=componentFile) file.close() for componentElt in xmlDocument.iter(tag="Component"): break # use presentation relationships for broader and narrower concepts arcrole = XbrlConst.parentChild # sort URIs by definition linkroleUris = [] relationshipSet = dts.relationshipSet(arcrole) if relationshipSet: for linkroleUri in relationshipSet.linkRoleUris: modelRoleTypes = dts.roleTypes.get(linkroleUri) if modelRoleTypes: roledefinition = (modelRoleTypes[0].genLabel(strip=True) or modelRoleTypes[0].definition or linkroleUri) else: roledefinition = linkroleUri linkroleUris.append((roledefinition, linkroleUri)) linkroleUris.sort() # for each URI in definition order for roledefinition, linkroleUri in linkroleUris: elt = etree.SubElement(componentElt, "Network", attrib={ "identifier": linkroleUri, "label": roledefinition }) linkRelationshipSet = dts.relationshipSet(arcrole, linkroleUri) for rootConcept in linkRelationshipSet.rootConcepts: genConcept(dts, elt, rootConcept, None, arcrole, linkRelationshipSet, set()) fh = open(componentFile, "w", encoding="utf-8") XmlUtil.writexml(fh, xmlDocument, encoding="utf-8") fh.close() dts.info( "info:saveCHComponentFile", _("Component file for %(entryFile)s in file %(componentOutputFile)s."), modelObject=dts, entryFile=dts.uri, componentOutputFile=componentFile)
def generateCHComponent(dts, componentFile): if dts.fileSource.isArchive: return import os, io from arelle import XmlUtil, XbrlConst file = io.StringIO(''' <nsmap> <Component/> </nsmap> ''' ) from arelle.ModelObjectFactory import parser parser, parserLookupName, parserLookupClass = parser(dts,None) xmlDocument = etree.parse(file,parser=parser,base_url=componentFile) file.close() for componentElt in xmlDocument.iter(tag="Component"): break # use presentation relationships for broader and narrower concepts arcrole = XbrlConst.parentChild # sort URIs by definition linkroleUris = [] relationshipSet = dts.relationshipSet(arcrole) if relationshipSet: for linkroleUri in relationshipSet.linkRoleUris: modelRoleTypes = dts.roleTypes.get(linkroleUri) if modelRoleTypes: roledefinition = (modelRoleTypes[0].genLabel(strip=True) or modelRoleTypes[0].definition or linkroleUri) else: roledefinition = linkroleUri linkroleUris.append((roledefinition, linkroleUri)) linkroleUris.sort() # for each URI in definition order for roledefinition, linkroleUri in linkroleUris: elt = etree.SubElement(componentElt, "Network", attrib={ "identifier": linkroleUri, "label": roledefinition}) linkRelationshipSet = dts.relationshipSet(arcrole, linkroleUri) for rootConcept in linkRelationshipSet.rootConcepts: genConcept(dts, elt, rootConcept, None, arcrole, linkRelationshipSet, set()) fh = open(componentFile, "w", encoding="utf-8") XmlUtil.writexml(fh, xmlDocument, encoding="utf-8") fh.close() dts.info("info:saveCHComponentFile", _("Component file for %(entryFile)s in file %(componentOutputFile)s."), modelObject=dts, entryFile=dts.uri, componentOutputFile=componentFile)
def close(self, noWrite=False): if self.type == CSV: if not isinstance(self.outfile, FileNamedStringIO): self.csvFile.close() elif not noWrite: fileType = TYPENAMES[self.type] try: from arelle import XmlUtil if isinstance(self.outfile, FileNamedStringIO): fh = self.outfile else: fh = open(self.outfile, u"w", encoding=u"utf-8") if self.type == JSON: fh.write(json.dumps(self.jsonObject, ensure_ascii=False)) else: XmlUtil.writexml(fh, self.xmlDoc, encoding=u"utf-8", xmlcharrefreplace= (self.type == HTML) ) if not isinstance(self.outfile, FileNamedStringIO): fh.close() self.modelXbrl.info(u"info", _(u"Saved output %(type)s to %(file)s"), file=self.outfile, type=fileType) except (IOError, EnvironmentError), err: self.modelXbrl.exception(u"arelle:htmlIOError", _(u"Failed to save output %(type)s to %(file)s: \s%(error)s"), file=self.outfile, type=fileType, error=err)
def generateSkos(dts, skosFile): try: import os, io from arelle import XmlUtil, XbrlConst from arelle.ViewUtil import viewReferences, referenceURI skosNs = "http://www.w3.org/2004/02/skos/core#" rdfNs = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" dts.modelManager.showStatus("initializing SKOS document") file = io.StringIO(''' <!DOCTYPE rdf:RDF> <nsmap> <rdf:RDF xmlns="urn:cgi:classifier:CGI:XBRL:201204#" xml:base="urn:cgi:classifierScheme:CGI:XBRL:201204" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:owl2xml="http://www.w3.org/2006/12/owl2-xml#" xmlns:p1="#" xmlns:owl="http://www.w3.org/2002/07/owl#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xbrl-201204="urn:cgi:classifier:CGI:XBRL:201204#" xmlns:skos="http://www.w3.org/2004/02/skos/core#"> <owl:Ontology rdf:about="" /> <!-- Annotation properties --> <owl:AnnotationProperty rdf:about="http://purl.org/dc/elements/1.1/date" /> <owl:AnnotationProperty rdf:about="http://purl.org/dc/elements/1.1/source" /> <owl:AnnotationProperty rdf:about="http://purl.org/dc/elements/1.1/title" /> <owl:AnnotationProperty rdf:about="http://purl.org/dc/elements/1.1/description" /> <owl:AnnotationProperty rdf:about="http://purl.org/dc/elements/1.1/contributor" /> <owl:AnnotationProperty rdf:about="http://purl.org/dc/elements/1.1/creator" /> <owl:AnnotationProperty rdf:about="http://purl.org/dc/elements/1.1/format" /> <owl:AnnotationProperty rdf:about="http://www.w3.org/2002/07/owl#versionInfo" /> <!-- Object Properties --> <!-- http://www.w3.org/2004/02/skos/core#broader --> <owl:ObjectProperty rdf:about="http://www.w3.org/2004/02/skos/core#broader" /> <!-- http://www.w3.org/2004/02/skos/core#changeNote --> <owl:ObjectProperty rdf:about="http://www.w3.org/2004/02/skos/core#changeNote" /> <!-- http://www.w3.org/2004/02/skos/core#hasTopConcept --> <owl:ObjectProperty rdf:about="http://www.w3.org/2004/02/skos/core#hasTopConcept" /> <!-- http://www.w3.org/2004/02/skos/core#inScheme --> <owl:ObjectProperty rdf:about="http://www.w3.org/2004/02/skos/core#inScheme" /> <!-- http://www.w3.org/2004/02/skos/core#topConceptOf --> <owl:ObjectProperty rdf:about="http://www.w3.org/2004/02/skos/core#topConceptOf" /> <!-- Data properties --> <!-- http://www.w3.org/2004/02/skos/core#definition --> <owl:DatatypeProperty rdf:about="http://www.w3.org/2004/02/skos/core#definition" /> <!-- http://www.w3.org/2004/02/skos/core#editorialNote --> <owl:DatatypeProperty rdf:about="http://www.w3.org/2004/02/skos/core#editorialNote" /> <!-- http://www.w3.org/2004/02/skos/core#historyNote --> <owl:DatatypeProperty rdf:about="http://www.w3.org/2004/02/skos/core#historyNote" /> <!-- http://www.w3.org/2004/02/skos/core#notation --> <owl:DatatypeProperty rdf:about="http://www.w3.org/2004/02/skos/core#notation" /> <!-- http://www.w3.org/2004/02/skos/core#prefLabel --> <owl:DatatypeProperty rdf:about="http://www.w3.org/2004/02/skos/core#prefLabel" /> <!-- Classes --> <!-- http://www.w3.org/2002/07/owl#Thing --> <owl:Class rdf:about="http://www.w3.org/2002/07/owl#Thing" /> <!-- http://www.w3.org/2004/02/skos/core#Concept --> <owl:Class rdf:about="http://www.w3.org/2004/02/skos/core#Concept" /> <!-- http://www.w3.org/2004/02/skos/core#ConceptScheme --> <owl:Class rdf:about="http://www.w3.org/2004/02/skos/core#ConceptScheme" /> <!-- Individuals --> </rdf:RDF></nsmap> <!-- Generated by the Arelle(r) http://arelle.org --> ''' ) from arelle.ModelObjectFactory import parser parser, parserLookupName, parserLookupClass = parser(dts,None) from lxml import etree xmlDocument = etree.parse(file,parser=parser,base_url=skosFile) file.close() xmlRootElement = xmlDocument.getroot() #xmlDocument.getroot().init(self) ## is this needed ?? for rdfElement in xmlDocument.iter(tag="{http://www.w3.org/1999/02/22-rdf-syntax-ns#}RDF"): break numSchemes = 0 numConcepts = 0 # use presentation relationships for broader and narrower concepts relationshipSet = dts.relationshipSet(XbrlConst.parentChild) def conceptUri(concept): return concept.qname.namespaceURI + "#" + concept.qname.localName def namespaceUri(qname): return qname.namespaceURI + "#" + qname.prefix priorSchemeSibling = None schemeNamespaces = set() dts.modelManager.showStatus("setting SKOS concepts from XBRL concepts") for qn, concept in sorted(dts.qnameConcepts.items(), key=lambda item:str(item[0])): if concept.modelDocument.targetNamespace not in ( XbrlConst.xbrli, XbrlConst.link, XbrlConst.xlink, XbrlConst.xl, XbrlConst.xbrldt): if qn.namespaceURI not in schemeNamespaces: # add conceptScheme numSchemes += 1 skosElt = etree.Element("{http://www.w3.org/2004/02/skos/core#}ConceptScheme") skosElt.set("{http://www.w3.org/1999/02/22-rdf-syntax-ns#}about", namespaceUri(qn)) elt = etree.SubElement(skosElt, "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}type") elt.set("{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource", "http://www.w3.org/2002/07/owl#Thing") elt = etree.SubElement(skosElt, "{http://www.w3.org/2004/02/skos/core#}notation") elt.text = str(qn.prefix) schemeNamespaces.add(qn.namespaceURI) if priorSchemeSibling is not None: priorSchemeSibling.addnext(skosElt) else: rdfElement.append(skosElt) priorSchemeSibling = skosElt numConcepts += 1 skosElt = etree.SubElement(rdfElement, "{http://www.w3.org/2004/02/skos/core#}Concept") skosElt.set("{http://www.w3.org/1999/02/22-rdf-syntax-ns#}about", conceptUri(concept)) elt = etree.SubElement(skosElt, "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}type") elt.set("{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource", "http://www.w3.org/2002/07/owl#Thing") elt = etree.SubElement(skosElt, "{http://www.w3.org/2004/02/skos/core#}notation") elt.text = str(concept.qname) definition = concept.label(preferredLabel=XbrlConst.documentationLabel, lang="en", strip=True, fallbackToQname=False) if definition: elt = etree.SubElement(skosElt, "{http://www.w3.org/2004/02/skos/core#}definition") elt.text = definition else: # if no definition, look for any references references = viewReferences(concept) if references: elt = etree.SubElement(skosElt, "{http://www.w3.org/2004/02/skos/core#}definition") elt.text = references linkedReferenceURI = referenceURI(concept) if linkedReferenceURI: # link to reference elt = etree.SubElement(skosElt, "{http://www.w3.org/2004/02/skos/core#}definition") elt.text = linkedReferenceURI labelsRelationshipSet = dts.relationshipSet(XbrlConst.conceptLabel) if labelsRelationshipSet: for modelLabelRel in labelsRelationshipSet.fromModelObject(concept): label = modelLabelRel.toModelObject if label.role == XbrlConst.standardLabel: elt = etree.SubElement(skosElt, "{http://www.w3.org/2004/02/skos/core#}prefLabel") elt.set("{http://www.w3.org/XML/1998/namespace}lang", label.xmlLang) elt.text = label.text.strip() for rel in relationshipSet.fromModelObject(concept): # narrower elt = etree.SubElement(skosElt, "{http://www.w3.org/2004/02/skos/core#}narrower") elt.set("{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource", conceptUri(rel.toModelObject)) for rel in relationshipSet.toModelObject(concept): # broader elt = etree.SubElement(skosElt, "{http://www.w3.org/2004/02/skos/core#}broader") elt.set("{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource", conceptUri(rel.fromModelObject)) elt = etree.SubElement(skosElt, "{http://www.w3.org/2004/02/skos/core#}inScheme") elt.set("{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource", namespaceUri(qn)) dts.modelManager.showStatus("saving SKOS file") fh = open(skosFile, "w", encoding="utf-8") XmlUtil.writexml(fh, xmlDocument, encoding="utf-8") fh.close() dts.info("info:saveSKOS", _("SKOS of %(entryFile)s has %(numberOfConcepts)s concepts in SKOS RDF file %(skosOutputFile)s."), modelObject=dts, entryFile=dts.uri, numberOfConcepts=numConcepts, skosOutputFile=skosFile) dts.modelManager.showStatus("ready", 3000) except Exception as ex: dts.error("exception", _("SKOS generation exception: %(error)s"), error=ex, modelXbrl=dts, exc_info=True)
def generateHtmlEbaTablesetFiles(dts, indexFile, lang="en"): try: import os, io from arelle import Version, XbrlConst, XmlUtil from arelle.ViewFileRenderedGrid import viewRenderedGrid from arelle.ModelRenderingObject import ModelEuTable, ModelTable numTableFiles = 0 file = io.StringIO(''' <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Left"> <link type="text/css" rel="stylesheet" href="http://arelle.org/files/EBA/style20121210/eba.css" /> </head> <body class="LTR IE7 ENGB"> <ul class="CMSListMenuUL" id="Vertical2"/> </body> </html> ''') from arelle.ModelObjectFactory import parser parser, parserLookupName, parserLookupClass = parser(dts, None) from lxml import etree indexDocument = etree.parse(file, parser=parser, base_url=indexFile) file.close() #xmlDocument.getroot().init(self) ## is this needed ?? for listElt in indexDocument.iter( tag="{http://www.w3.org/1999/xhtml}ul"): break class nonTkBooleanVar(): def __init__(self, value=True): self.value = value def set(self, value): self.value = value def get(self): return self.value class View(): def __init__(self, tableOrELR, ignoreDimValidity, xAxisChildrenFirst, yAxisChildrenFirst): self.tblELR = tableOrELR # context menu boolean vars (non-tkinter boolean self.ignoreDimValidity = nonTkBooleanVar( value=ignoreDimValidity) self.xAxisChildrenFirst = nonTkBooleanVar( value=xAxisChildrenFirst) self.yAxisChildrenFirst = nonTkBooleanVar( value=yAxisChildrenFirst) indexBase = indexFile.rpartition(".")[0] groupTableRels = dts.modelXbrl.relationshipSet(XbrlConst.euGroupTable) modelTables = [] tblCssExtras = ''' body {background-image:url('http://arelle.org/files/EBA/style20121210/lhsbackground.jpg')} table {background:#fff} ''' # order number is missing def viewTable(modelTable): if modelTable is None: return if isinstance(modelTable, (ModelEuTable, ModelTable)): # status dts.modelManager.cntlr.addToLog("viewing: " + modelTable.id) # for table file name, use table ELR tblFile = os.path.join(os.path.dirname(indexFile), modelTable.id + ".html") viewRenderedGrid(dts, tblFile, lang=lang, sourceView=View(modelTable, False, False, True), cssExtras=tblCssExtras) # generaate menu entry elt = etree.SubElement(listElt, "{http://www.w3.org/1999/xhtml}li") elt.set("class", "CMSListMenuLI") elt.set("id", modelTable.id) elt = etree.SubElement(elt, "{http://www.w3.org/1999/xhtml}a") elt.text = modelTable.genLabel(lang=lang, strip=True) elt.set("class", "CMSListMenuLink") elt.set("href", "javascript:void(0)") elt.set( "onClick", "javascript:parent.body.location.href='{0}';".format( modelTable.id + ".html")) elt.text = modelTable.genLabel(lang=lang, strip=True) else: # just a header # generaate menu entry elt = etree.SubElement(listElt, "{http://www.w3.org/1999/xhtml}li") elt.set("class", "CMSListMenuLink") elt.set("id", modelTable.id) elt.text = modelTable.label(lang=lang, strip=True) for rel in groupTableRels.fromModelObject(modelTable): viewTable(rel.toModelObject) for rootConcept in groupTableRels.rootConcepts: sourceline = 0 for rel in dts.modelXbrl.relationshipSet( XbrlConst.euGroupTable).fromModelObject(rootConcept): sourceline = rel.sourceline break modelTables.append((rootConcept, sourceline)) for modelTable, order in sorted(modelTables, key=lambda x: x[1]): viewTable(modelTable) with open(indexBase + "FormsFrame.html", "wt", encoding="utf-8") as fh: XmlUtil.writexml(fh, indexDocument, encoding="utf-8") with open(indexFile, "wt", encoding="utf-8") as fh: fh.write(''' <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1"> <title>European Banking Authority - EBA - FINREP Taxonomy</title> <meta name="generator" content="Arelle(r) {0}" /> <meta name="provider" content="Aguilonius(r)" /> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <meta http-equiv="pragma" content="no-cache" /> <meta http-equiv="content-style-type" content="text/css" /> <meta http-equiv="content-script-type" content="text/javascript" /> <link type="text/css" rel="stylesheet" href="http://arelle.org/files/EBA/style20121210/eba.css" /> </head> <frameset border="0" frameborder="0" rows="90,*"> <frame name="head" src="{1}" scrolling="no" marginwidth="0" marginheight="10"/> <frameset bordercolor="#0000cc" border="10" frameborder="no" framespacing="0" cols="360, *"> <frame src="{2}" name="menu" bordercolor="#0000cc"/> <frame src="{3}" name="body" bordercolor="#0000cc"/> </frameset> </frameset> '''.format( Version.version, os.path.basename(indexBase) + "TopFrame.html", os.path.basename(indexBase) + "FormsFrame.html", os.path.basename(indexBase) + "CenterLanding.html", )) with open(indexBase + "TopFrame.html", "wt", encoding="utf-8") as fh: fh.write(''' <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Top"> <link type="text/css" rel="stylesheet" href="http://arelle.org/files/EBA/style20121210/eba.css" /> </head> <body class="LTR IE7 ENGB"> <div id="topsection"> <div id="topsectionLeft" style="cursor:pointer;" onclick="location.href='http://www.eba.europa.eu/home.aspx';"></div> <div id="topsectionRight"></div> <div id="topnavigation"> <ul id="menuElem"> <li><a href="http://www.eba.europa.eu/topnav/Contacts.aspx">Contacts</a></li> <li><a href="http://www.eba.europa.eu/topnav/Links.aspx">Links</a></li> <li><a href="http://www.eba.europa.eu/topnav/Sitemap.aspx">Sitemap</a></li> <li><a href="http://www.eba.europa.eu/topnav/Legal-Notice.aspx">Legal Notice</a></li> </ul> </div> </body> </html> ''') with open(indexBase + "CenterLanding.html", "wt", encoding="utf-8") as fh: fh.write(''' <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Center"> <link type="text/css" rel="stylesheet" href="http://http://arelle.org/files/EBA/style20121210/eba.css" /> </head> <body class="LTR IE7 ENGB"> <div id="plc_lt_zoneContent_usercontrol_userControlElem_ContentPanel"> <div id="plc_lt_zoneContent_usercontrol_userControlElem_PanelTitle"> <div id="pagetitle" style="float:left;width:500px;"> <h1>Taxonomy Tables Viewer</h1> </div> </div> </div> <div style="clear:both;"></div> <div id="contentcenter"> <p style="text-align: justify; margin-top: 0pt; margin-bottom: 0pt">Please select tables to view by clicking in the left column.</p> </div> </body> </html> ''') # to merge gif's and style sheets, use a zipfile sibling of the python plug-in file. #import zipfile #zf = zipfile.ZipFile(__file__.rpartition('.')[0] + "Files.zip", mode="r") #zf.extractall(path=os.path.dirname(indexBase)) #zf.close() dts.info( "info:saveEBAtables", _("Tables index file of %(entryFile)s has %(numberTableFiles)s table files with index file %(indexFile)s." ), modelObject=dts, entryFile=dts.uri, numberTableFiles=numTableFiles, indexFile=indexFile) dts.modelManager.showStatus(_("Saved EBA HTML Table Files"), 5000) except Exception as ex: dts.error("exception", _("HTML EBA Tableset files generation exception: %(error)s"), error=ex, modelXbrl=dts, exc_info=True)
def saveInstance(self): with open(self.modelDocument.filepath, "w", encoding='utf-8') as fh: XmlUtil.writexml(fh, self.modelDocument.xmlDocument, encoding="utf-8")
def runFromExcel(self, options): #testGenFileName = options.excelfilename testGenFileName = r"C:\Users\Herm Fischer\Documents\mvsl\projects\XBRL.org\conformance-versioning\trunk\versioningReport\conf\creation-index.xls" testGenDir = os.path.dirname(testGenFileName) schemaDir = os.path.dirname(testGenDir) + os.sep + "schema" timeNow = XmlUtil.dateunionValue(datetime.datetime.now()) if options.testfiledate: today = options.testfiledate else: today = XmlUtil.dateunionValue(datetime.date.today()) startedAt = time.time() LogHandler(self) # start logger self.logMessages = [] logMessagesFile = testGenDir + os.sep + 'log-generation-messages.txt' modelTestcases = ModelXbrl.create(self.modelManager, url=testGenFileName, isEntry=True) testcaseIndexBook = xlrd.open_workbook(testGenFileName) testcaseIndexSheet = testcaseIndexBook.sheet_by_index(0) self.addToLog(_("[info] xls loaded in {0:.2} secs at {1}").format(time.time() - startedAt, timeNow)) # start index file indexFiles = [testGenDir + os.sep + 'creation-testcases-index.xml', testGenDir + os.sep + 'consumption-testcases-index.xml'] indexDocs = [] testcasesElements = [] for purpose in ("Creation","Consumption"): file = io.StringIO( #'<?xml version="1.0" encoding="UTF-8"?>' '<!-- XBRL Versioning 1.0 {0} Tests -->' '<!-- Copyright 2011 XBRL International. All Rights Reserved. -->' '<?xml-stylesheet type="text/xsl" href="infrastructure/testcases-index.xsl"?>' '<testcases name="XBRL Versioning 1.0 {0} Tests" ' ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' ' xsi:noNamespaceSchemaLocation="infrastructure/testcases-index.xsd">' '</testcases>'.format(purpose, today) ) doc = etree.parse(file) file.close() indexDocs.append(doc) testcasesElements.append(doc.getroot()) priorTestcasesDir = None testcaseFiles = None testcaseDocs = None for iRow in range(1, testcaseIndexSheet.nrows): try: row = testcaseIndexSheet.row(iRow) if (row[0].ctype == xlrd.XL_CELL_EMPTY or # must have directory row[1].ctype == xlrd.XL_CELL_EMPTY or # from row[2].ctype == xlrd.XL_CELL_EMPTY): # to continue testDir = row[0].value uriFrom = row[1].value uriTo = row[2].value overrideReport = row[3].value description = row[4].value if description is None or len(description) == 0: continue # test not ready to run assignment = row[5].value expectedEvents = row[6].value # comma space separated if multiple note = row[7].value useCase = row[8].value base = os.path.join(os.path.dirname(testGenFileName),testDir) + os.sep self.addToLog(_("[info] testcase uriFrom {0}").format(uriFrom)) if uriFrom and uriTo and assignment.lower() not in ("n.a.", "error") and expectedEvents != "N.A.": modelDTSfrom = modelDTSto = None for URIs, msg, isFrom in ((uriFrom, _("loading from DTS"), True), (uriTo, _("loading to DTS"), False)): if ',' not in URIs: modelDTS = ModelXbrl.load(self.modelManager, URIs, msg, base=base) else: modelDTS = ModelXbrl.create(self.modelManager, ModelDocument.Type.DTSENTRIES, self.webCache.normalizeUrl(URIs.replace(", ","_") + ".dts", base), isEntry=True) DTSdoc = modelDTS.modelDocument DTSdoc.inDTS = True for uri in URIs.split(','): doc = ModelDocument.load(modelDTS, uri.strip(), base=base) if doc is not None: DTSdoc.referencesDocument[doc] = "import" #fake import doc.inDTS = True if isFrom: modelDTSfrom = modelDTS else: modelDTSto = modelDTS if modelDTSfrom is not None and modelDTSto is not None: # generate differences report reportUri = uriFrom.partition(',')[0] # first file reportDir = os.path.dirname(reportUri) if reportDir: reportDir += os.sep reportName = os.path.basename(reportUri).replace("from.xsd","report.xml") reportFile = reportDir + "out" + os.sep + reportName #reportFile = reportDir + "report" + os.sep + reportName reportFullPath = self.webCache.normalizeUrl( reportFile, base) testcasesDir = os.path.dirname(os.path.dirname(reportFullPath)) if testcasesDir != priorTestcasesDir: # close prior report if priorTestcasesDir: for i,testcaseFile in enumerate(testcaseFiles): with open(testcaseFile, "w", encoding="utf-8") as fh: XmlUtil.writexml(fh, testcaseDocs[i], encoding="utf-8") testcaseName = os.path.basename(testcasesDir) testcaseFiles = [testcasesDir + os.sep + testcaseName + "-creation-testcase.xml", testcasesDir + os.sep + testcaseName + "-consumption-testcase.xml"] for i,testcaseFile in enumerate(testcaseFiles): etree.SubElement(testcasesElements[i], "testcase", attrib={"uri": testcaseFile[len(testGenDir)+1:].replace("\\","/")} ) # start testcase file testcaseDocs = [] testcaseElements = [] testcaseNumber = testcaseName[0:4] if testcaseNumber.isnumeric(): testcaseNumberElement = "<number>{0}</number>".format(testcaseNumber) testcaseName = testcaseName[5:] else: testcaseNumberElement = "" testDirSegments = testDir.split('/') if len(testDirSegments) >= 2 and '-' in testDirSegments[1]: testedModule = testDirSegments[1][testDirSegments[1].index('-') + 1:] else: testedModule = '' for purpose in ("Creation","Consumption"): file = io.StringIO( #'<?xml version="1.0" encoding="UTF-8"?>' '<!-- Copyright 2011 XBRL International. All Rights Reserved. -->' '<?xml-stylesheet type="text/xsl" href="../../../infrastructure/test.xsl"?>' '<testcase ' ' xmlns="http://xbrl.org/2008/conformance"' ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' ' xsi:schemaLocation="http://xbrl.org/2008/conformance ../../../infrastructure/test.xsd">' '<creator>' '<name>Roland Hommes</name>' '<email>[email protected]</email>' '</creator>' '{0}' '<name>{1}</name>' # '<description>{0}</description>' '<reference>' '{2}' '{3}' '</reference>' '</testcase>'.format(testcaseNumberElement, testcaseName, '<name>{0}</name>'.format(testedModule) if testedModule else '', '<id>{0}</id>'.format(useCase) if useCase else '') ) doc = etree.parse(file) file.close() testcaseDocs.append(doc) testcaseElements.append(doc.getroot()) priorTestcasesDir = testcasesDir variationSeq = 1 try: os.makedirs(os.path.dirname(reportFullPath)) except WindowsError: pass # dir already exists modelVersReport = ModelVersReport.ModelVersReport(modelTestcases) modelVersReport.diffDTSes(reportFullPath,modelDTSfrom, modelDTSto, assignment=assignment, schemaDir=schemaDir) # check for expected elements if expectedEvents: for expectedEvent in expectedEvents.split(","): if expectedEvent not in ("No change", "N.A."): prefix, sep, localName = expectedEvent.partition(':') if sep and len(modelVersReport.xmlDocument.findall( '//{{{0}}}{1}'.format( XbrlConst.verPrefixNS.get(prefix), localName))) == 0: modelTestcases.warning("warning", "Generated test case %(reportName)s missing expected event %(event)s", reportName=reportName, event=expectedEvent) modelVersReport.close() uriFromParts = uriFrom.split('_') if len(uriFromParts) >= 2: variationId = uriFromParts[1] else: variationId = "_{0:02n}".format(variationSeq) for i,testcaseElt in enumerate(testcaseElements): variationElement = etree.SubElement(testcaseElt, "{http://xbrl.org/2008/conformance}variation", attrib={"id": variationId}) nameElement = etree.SubElement(variationElement, "{http://xbrl.org/2008/conformance}description") nameElement.text = description ''' (removed per RH 2011/10/04 if note: paramElement = etree.SubElement(variationElement, "{http://xbrl.org/2008/conformance}description") paramElement.text = "Note: " + note if useCase: paramElement = etree.SubElement(variationElement, "{http://xbrl.org/2008/conformance}reference") paramElement.set("specification", "versioning-requirements") paramElement.set("useCase", useCase) ''' dataElement = etree.SubElement(variationElement, "{http://xbrl.org/2008/conformance}data") if i == 0: # result is report if expectedEvents: paramElement = etree.SubElement(dataElement, "{http://xbrl.org/2008/conformance}parameter", attrib={"name":"expectedEvent", "value":expectedEvents.replace(',',' ')}, nsmap={"conf":"http://xbrl.org/2008/conformance", None:""}) if assignment: paramElement = etree.SubElement(dataElement, "{http://xbrl.org/2008/conformance}parameter", attrib={"name":"assignment", "value":assignment}, nsmap={"conf":"http://xbrl.org/2008/conformance", None:""}) for schemaURIs, dtsAttr in ((uriFrom,"from"), (uriTo,"to")): for schemaURI in schemaURIs.split(","): schemaElement = etree.SubElement(dataElement, "{http://xbrl.org/2008/conformance}schema") schemaElement.set("dts",dtsAttr) if i == 0: schemaElement.set("readMeFirst","true") schemaElement.text=os.path.basename(schemaURI.strip()) resultElement = etree.SubElement(variationElement, "{http://xbrl.org/2008/conformance}result") reportElement = etree.SubElement(resultElement if i == 0 else dataElement, "{http://xbrl.org/2008/conformance}versioningReport") if i == 1: reportElement.set("readMeFirst","true") reportElement.text = "report/" + reportName variationSeq += 1 except Exception as err: modelTestcases.error("exception", _("Exception: %(error)s, Excel row: %(excelRow)s"), error=err, excelRow=iRow, exc_info=True) # add tests-error-code index files to consumption for testcaseFile in self.testcaseFiles(testGenDir + os.sep + "tests-error-code"): etree.SubElement(testcasesElements[1], "testcase", attrib={"uri": testcaseFile[len(testGenDir)+1:].replace("\\","/")} ) with open(logMessagesFile, "w") as fh: fh.writelines(self.logMessages) if priorTestcasesDir: for i,testcaseFile in enumerate(testcaseFiles): with open(testcaseFile, "w", encoding="utf-8") as fh: XmlUtil.writexml(fh, testcaseDocs[i], encoding="utf-8") for i,indexFile in enumerate(indexFiles): with open(indexFile, "w", encoding="utf-8") as fh: XmlUtil.writexml(fh, indexDocs[i], encoding="utf-8")
def runFromExcel(self, options): testGenFileName = options.excelfilename #testGenFileName = r"C:\Users\Herm Fischer\Documents\mvsl\projects\XBRL.org\conformance-versioning\trunk\versioningReport\conf\creation\1000-2000-index.xls" testGenDir = os.path.dirname(testGenFileName) timeNow = XmlUtil.dateunionValue(datetime.datetime.now()) if options.testfiledate: today = options.testfiledate else: today = XmlUtil.dateunionValue(datetime.date.today()) startedAt = time.time() self.logMessages = [] logMessagesFile = testGenDir + os.sep + 'logGenerationMessages.txt' modelTestcases = ModelXbrl.create(self.modelManager) testcaseIndexBook = xlrd.open_workbook(testGenFileName) testcaseIndexSheet = testcaseIndexBook.sheet_by_index(0) self.addToLog( _("[info] xls loaded in {0:.2} secs at {1}").format( time.time() - startedAt, timeNow)) # start index file indexFiles = [ testGenDir + os.sep + 'creationTestcasesIndex.xml', testGenDir + os.sep + 'consumptionTestcasesIndex.xml' ] indexDocs = [ xml.dom.minidom.parseString( '<?xml version="1.0" encoding="UTF-8"?>' '<!-- XBRL Versioning 1.0 {0} Tests -->' '<!-- Copyright 2011 XBRL International. All Rights Reserved. -->' '<?xml-stylesheet type="text/xsl" href="infrastructure/testcases-index.xsl"?>' '<testcases name="XBRL Versioning 1.0 Consumption Tests" date="{1}" ' ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' ' xsi:noNamespaceSchemaLocation="infrastructure/testcases-index.xsd">' '</testcases>'.format(purpose, today)) for purpose in ("Creation", "Consumption") ] testcasesElements = [ XmlUtil.child(indexDoc, None, "testcases") for indexDoc in indexDocs ] priorTestcasesDir = None testcaseFiles = None testcaseDocs = None for iRow in range(1, testcaseIndexSheet.nrows): row = testcaseIndexSheet.row(iRow) if row[0].ctype == xlrd.XL_CELL_EMPTY or row[ 1].ctype == xlrd.XL_CELL_EMPTY or row[ 2].ctype == xlrd.XL_CELL_EMPTY: continue testDir = row[0].value uriFrom = row[1].value uriTo = row[2].value intention = row[3].value if intention is None or len(intention) == 0: continue # test not ready to run reason = row[4].value expectedEvent = row[5].value base = os.path.join(os.path.dirname(testGenFileName), testDir) + os.sep self.addToLog(_("[info] testcase uriFrom {0}").format(uriFrom)) if uriFrom and uriTo and reason.lower() not in ( "n.a.", "error") and expectedEvent != "N.A.": for URIs, msg, isFrom in ((uriFrom, _("loading from DTS"), True), (uriTo, _("loading to DTS"), False)): if ',' not in URIs: modelDTS = ModelXbrl.load(self.modelManager, URIs, msg, base=base) else: modelDTS = ModelXbrl.create( self.modelManager, ModelDocument.Type.DTSENTRIES, self.webCache.normalizeUrl( URIs.replace(", ", "_") + ".dts", base), isEntry=True) DTSdoc = modelDTS.modelDocument DTSdoc.inDTS = True for uri in URIs.split(','): doc = ModelDocument.load(modelDTS, uri.strip(), base=base) DTSdoc.referencesDocument[ doc] = "import" #fake import doc.inDTS = True if isFrom: modelDTSfrom = modelDTS else: modelDTSto = modelDTS if modelDTSfrom and modelDTSto: # generate differences report reportUri = uriFrom.partition(',')[0] # first file reportDir = os.path.dirname(reportUri) if reportDir: reportDir += os.sep reportName = os.path.basename(reportUri).replace( "from.xsd", "report.xml") reportFile = reportDir + "report" + os.sep + reportName reportFullPath = self.webCache.normalizeUrl( reportFile, base) testcasesDir = os.path.dirname( os.path.dirname(reportFullPath)) if testcasesDir != priorTestcasesDir: # close prior report if priorTestcasesDir: for i, testcaseFile in enumerate(testcaseFiles): with open(testcaseFile, "w", encoding="utf-8") as fh: XmlUtil.writexml(fh, testcaseDocs[i], encoding="utf-8") testcaseName = os.path.basename(testcasesDir) testcaseFiles = [ testcasesDir + os.sep + testcaseName + "-creation-testcase.xml", testcasesDir + os.sep + testcaseName + "-consumption-testcase.xml" ] for i, testcaseFile in enumerate(testcaseFiles): XmlUtil.addChild( testcasesElements[i], None, "testcase", ("uri", testcaseFile[len(testGenDir) + 1:].replace("\\", "/"))) # start testcase file testcaseDocs = [ xml.dom.minidom.parseString( '<?xml version="1.0" encoding="UTF-8"?>' '<!-- Copyright 2011 XBRL International. All Rights Reserved. -->' '<?xml-stylesheet type="text/xsl" href="../../../infrastructure/test.xsl"?>' '<testcase name="XBRL Versioning 1.0 {1} Tests" date="{2}" ' ' xmlns="http://xbrl.org/2008/conformance"' ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' ' xsi:schemaLocation="http://xbrl.org/2008/conformance ../../../infrastructure/test.xsd">' '<creator>' '<name>Roland Hommes</name>' '<email>[email protected]</email>' '</creator>' '<name>{0}</name>' '<description>{0}</description>' '</testcase>'.format(testcaseName, purpose, today)) for purpose in ("Creation", "Consumption") ] testcaseElements = [ XmlUtil.child(testcaseDoc, conformanceNS, "testcase") for testcaseDoc in testcaseDocs ] priorTestcasesDir = testcasesDir variationID = 1 try: os.makedirs(os.path.dirname(reportFullPath)) except WindowsError: pass # dir already exists modelVersReport = ModelVersReport.ModelVersReport( modelTestcases) modelVersReport.diffDTSes(reportFullPath, modelDTSfrom, modelDTSto) # check for expected elements if expectedEvent and expectedEvent not in ("No change", "N.A."): if len( modelVersReport.xmlDocument. getElementsByTagNameNS('*', expectedEvent)) == 0: modelTestcases.error( "Generated test case {0} missing expected event {1}" .format(reportName, expectedEvent), "wrn", "missingEvent") modelVersReport.close([]) for i, testcaseElt in enumerate(testcaseElements): variationElement = XmlUtil.addChild( testcaseElt, conformanceNS, "variation", attributes=("id", "_{0:02n}".format(variationID))) XmlUtil.addChild(variationElement, conformanceNS, "name", text=intention) dataElement = XmlUtil.addChild(variationElement, conformanceNS, "data") for schemaURIs, dtsAttr in ((uriFrom, "from"), (uriTo, "to")): for schemaURI in schemaURIs.split(","): XmlUtil.addChild( dataElement, conformanceNS, "schema", attributes=((("dts", dtsAttr), ) + ((("readMeFirst", "true"), ) if i == 0 else ())), text=os.path.basename(schemaURI.strip())) resultElement = XmlUtil.addChild( variationElement, conformanceNS, "result") XmlUtil.addChild( resultElement if i == 0 else dataElement, conformanceNS, "versioningReport", attributes=(("readMeFirst", "true") if i == 1 else ()), text="report/" + reportName) variationID += 1 with open(logMessagesFile, "w") as fh: fh.writelines(self.logMessages) if priorTestcasesDir: for i, testcaseFile in enumerate(testcaseFiles): with open(testcaseFile, "w", encoding="utf-8") as fh: XmlUtil.writexml(fh, testcaseDocs[i], encoding="utf-8") for i, indexFile in enumerate(indexFiles): with open(indexFile, "w", encoding="utf-8") as fh: XmlUtil.writexml(fh, indexDocs[i], encoding="utf-8")
def generateFormulaLB(cntlr, sphinxFiles, generatedSphinxFormulasDirectory): if sys.version[0] >= '3': from arelle.pyparsing.pyparsing_py3 import lineno else: from pyparsing import lineno from .SphinxContext import SphinxContext from .SphinxValidator import validate msgFile = None sourceString = None # logMessage operates without an instance document or ModelXbrl, so it simulates log function def logMessage(severity, code, text, **kwargs): if "sourceFileLines" in kwargs: # use pairs of file and line number fileLines = ", ".join((file + (" " + str(line)) if line else "") for file, line in kwargs["sourceFileLines"]) elif "sourceFileLine" in kwargs: file, line in kwargs["sourceFileLine"] fileLines = file + (" " + str(line)) if line else "" else: fileLines = "" if not fileLines: fileLines = ", " + fileLines try: cntlr.addToLog("[{0}] {1}{2}".format( code, text % kwargs, fileLines)) except KeyError as err: cntlr.addToLog("[{0}] {1}: Missing message parameter: {2}; {3}".format( code, text, err, fileLines)) from arelle import XmlUtil sc = SphinxContext( parse(cntlr, logMessage, sphinxFiles) ) sc.logMessage = logMessage validate(logMessage, sc) assertionIDs = set() for prog in sc.sphinxProgs: sphinxFile = prog[0].fileName sphinxXmlns = { "xlink": 'http://www.w3.org/1999/xlink', "link": 'http://www.xbrl.org/2003/linkbase', "xbrli": 'http://www.xbrl.org/2003/instance', "generic": 'http://xbrl.org/2008/generic', "formula": 'http://xbrl.org/2008/formula', "validation": 'http://xbrl.org/2008/validation', "variable": 'http://xbrl.org/2008/variable', "label": 'http://xbrl.org/2008/label', "ca": 'http://xbrl.org/2008/assertion/consistency', "ea": 'http://xbrl.org/2008/assertion/existence', "va": 'http://xbrl.org/2008/assertion/value', "msg": 'http://xbrl.org/2010/message', "bf": 'http://xbrl.org/2008/filter/boolean', "cf": 'http://xbrl.org/2008/filter/concept', "df": 'http://xbrl.org/2008/filter/dimension', "gf": 'http://xbrl.org/2008/filter/general', "pf": 'http://xbrl.org/2008/filter/period', "uf": 'http://xbrl.org/2008/filter/unit', "xfi": 'http://www.xbrl.org/2008/function/instance', "xsi": 'http://www.w3.org/2001/XMLSchema-instance', "xs": 'http://www.w3.org/2001/XMLSchema', } for node in prog: if isinstance(node, astNamespaceDeclaration): sphinxXmlns[node.prefix] = node.namespace formulaFile = sphinxFile.rpartition(".")[0] + "-formula.xml" # save in generatedSphinxFormulasDirectory if specified and valid (exists) if generatedSphinxFormulasDirectory and os.path.isdir(generatedSphinxFormulasDirectory): formulaFile = os.path.join(generatedSphinxFormulasDirectory, os.path.basename(formulaFile)) xbrlLBfile = io.StringIO(''' <nsmap> <link:linkbase {0} xsi:schemaLocation="http://www.xbrl.org/2003/linkbase http://www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd" > <link:arcroleRef arcroleURI='http://xbrl.org/arcrole/2008/element-label' xlink:href='http://www.xbrl.org/2008/generic-label.xsd#element-label' xlink:type='simple'/> <link:arcroleRef arcroleURI='http://xbrl.org/arcrole/2008/variable-set' xlink:href='http://www.xbrl.org/2008/variable.xsd#variable-set' xlink:type='simple'/> <link:arcroleRef arcroleURI='http://xbrl.org/arcrole/2008/variable-filter' xlink:href='http://www.xbrl.org/2008/variable.xsd#variable-filter' xlink:type='simple'/> <link:arcroleRef arcroleURI='http://xbrl.org/arcrole/2008/variable-set-precondition' xlink:href='http://www.xbrl.org/2008/variable.xsd#variable-set-precondition' xlink:type='simple'/> <link:arcroleRef arcroleURI='http://xbrl.org/arcrole/2008/consistency-assertion-formula' xlink:href='http://www.xbrl.org/2008/consistency-assertion.xsd#consistency-assertion-formula' xlink:type='simple'/> <link:roleRef roleURI='http://www.xbrl.org/2008/role/link' xlink:href='http://www.xbrl.org/2008/generic-link.xsd#standard-link-role' xlink:type='simple'/> <link:roleRef roleURI='http://www.xbrl.org/2008/role/label' xlink:href='http://www.xbrl.org/2008/generic-label.xsd#standard-label' xlink:type='simple'/> <link:roleRef roleURI="http://www.xbrl.org/2010/role/message" xlink:type="simple" xlink:href="http://www.xbrl.org/2010/generic-message.xsd#standard-message"/> <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2010/assertion-unsatisfied-message" xlink:type="simple" xlink:href="http://www.xbrl.org/2010/validation-message.xsd#assertion-unsatisfied-message"/> <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2010/assertion-satisfied-message" xlink:type="simple" xlink:href="http://www.xbrl.org/2010/validation-message.xsd#assertion-satisfied-message"/> <link:arcroleRef arcroleURI='http://xbrl.org/arcrole/2008/boolean-filter' xlink:href='http://www.xbrl.org/2008/boolean-filter.xsd#boolean-filter' xlink:type='simple'/> <generic:link xlink:type="extended" xlink:role="http://www.xbrl.org/2003/role/link"/> </link:linkbase> </nsmap> <!-- Generated by Arelle(r) http://arelle.org --> '''.format('\n'.join("xmlns{0}='{1}'".format((":" + prefix) if prefix else "", namespace) for prefix, namespace in sphinxXmlns.items()) ) ) msgFile = os.path.basename(formulaFile) xmlDocument = etree.parse(xbrlLBfile,base_url=formulaFile) xbrlLBfile.close() nsmapElt = xmlDocument.getroot() #xmlDocument.getroot().init(self) ## is this needed ?? for lbElement in xmlDocument.iter(tag="{http://www.xbrl.org/2003/linkbase}linkbase"): break for e in xmlDocument.iter(tag="{http://xbrl.org/2008/generic}link"): sc.genLinkElement = e break class DocObj: # fake ModelDocument for namespaces def __init__(self): self.xmlRootElement = lbElement self.xmlDocument = xmlDocument docObj = DocObj() numRules = 0 sc.generatedVarNbr = 1 sc.xpathCode = None sc.bindAsSequence = False sc.nodeXpathVarBindings = {} for node in prog: if isinstance(node, (astFormulaRule, astReportRule, astValidationRule)): # form unique ID sc.assertionID = node.name if sc.assertionID in assertionIDs: for suffixNumber in range(1,10000): if sc.assertionID + str(suffixNumber) not in assertionIDs: sc.assertionID += str(suffixNumber) break assertionIDs.add(sc.assertionID) sc.assertionElt = etree.SubElement(sc.genLinkElement, "{http://xbrl.org/2008/assertion/value}valueAssertion", attrib={"{http://www.w3.org/1999/xlink}type": "resource", "{http://www.w3.org/1999/xlink}label": sc.assertionID, "id": sc.assertionID, "aspectModel": "dimensional", "implicitFiltering": "true"}) sc.assertionVarNames = {"factVar_"} sc.generalVarNames = {} if isinstance(node, astFormulaRule): sc.assertionElt.set("test", xpathCode(node.expr, sc)) msgType = "assertion-unsatisfied-message" elif isinstance(node, astReportRule): sc.tags["value"] = node.expr # no test expression needed msgType = "assertion-unsatisfied-message" elif isinstance(node, astValidationRule): sc.assertionElt.set("test", "not( " + xpathCode(node.expr, sc) + " )") msgType = "assertion-satisfied-message" genMessage(node.message, sc, msgType) sc.nodeXpathVarBindings.clear() with open(formulaFile, "w", encoding="utf-8") as fh: XmlUtil.writexml(fh, xmlDocument, encoding="utf-8") logMessage("INFO", "info:compileSphinx", _("Compiled Sphinx of %(sphinxFile)s has %(numberRules)s tables in file %(formulaFile)s."), sphinxFile=sphinxFiles, numberRules=numRules, formulaFile=formulaFile) logMessage = None sc.close() cntlr.showStatus("Finshed sphinx files {0}".format(", ".join(os.path.basename(f) for f in sphinxFiles)), 5000)
def generateSkos(dts, skosFile): try: import os, io from arelle import XmlUtil, XbrlConst from arelle.ViewUtil import viewReferences, referenceURI skosNs = "http://www.w3.org/2004/02/skos/core#" rdfNs = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" dts.modelManager.showStatus("initializing SKOS document") file = io.StringIO(''' <!DOCTYPE rdf:RDF> <nsmap> <rdf:RDF xmlns="urn:cgi:classifier:CGI:XBRL:201204#" xml:base="urn:cgi:classifierScheme:CGI:XBRL:201204" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:owl2xml="http://www.w3.org/2006/12/owl2-xml#" xmlns:p1="#" xmlns:owl="http://www.w3.org/2002/07/owl#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xbrl-201204="urn:cgi:classifier:CGI:XBRL:201204#" xmlns:skos="http://www.w3.org/2004/02/skos/core#"> <owl:Ontology rdf:about="" /> <!-- Annotation properties --> <owl:AnnotationProperty rdf:about="http://purl.org/dc/elements/1.1/date" /> <owl:AnnotationProperty rdf:about="http://purl.org/dc/elements/1.1/source" /> <owl:AnnotationProperty rdf:about="http://purl.org/dc/elements/1.1/title" /> <owl:AnnotationProperty rdf:about="http://purl.org/dc/elements/1.1/description" /> <owl:AnnotationProperty rdf:about="http://purl.org/dc/elements/1.1/contributor" /> <owl:AnnotationProperty rdf:about="http://purl.org/dc/elements/1.1/creator" /> <owl:AnnotationProperty rdf:about="http://purl.org/dc/elements/1.1/format" /> <owl:AnnotationProperty rdf:about="http://www.w3.org/2002/07/owl#versionInfo" /> <!-- Object Properties --> <!-- http://www.w3.org/2004/02/skos/core#broader --> <owl:ObjectProperty rdf:about="http://www.w3.org/2004/02/skos/core#broader" /> <!-- http://www.w3.org/2004/02/skos/core#changeNote --> <owl:ObjectProperty rdf:about="http://www.w3.org/2004/02/skos/core#changeNote" /> <!-- http://www.w3.org/2004/02/skos/core#hasTopConcept --> <owl:ObjectProperty rdf:about="http://www.w3.org/2004/02/skos/core#hasTopConcept" /> <!-- http://www.w3.org/2004/02/skos/core#inScheme --> <owl:ObjectProperty rdf:about="http://www.w3.org/2004/02/skos/core#inScheme" /> <!-- http://www.w3.org/2004/02/skos/core#topConceptOf --> <owl:ObjectProperty rdf:about="http://www.w3.org/2004/02/skos/core#topConceptOf" /> <!-- Data properties --> <!-- http://www.w3.org/2004/02/skos/core#definition --> <owl:DatatypeProperty rdf:about="http://www.w3.org/2004/02/skos/core#definition" /> <!-- http://www.w3.org/2004/02/skos/core#editorialNote --> <owl:DatatypeProperty rdf:about="http://www.w3.org/2004/02/skos/core#editorialNote" /> <!-- http://www.w3.org/2004/02/skos/core#historyNote --> <owl:DatatypeProperty rdf:about="http://www.w3.org/2004/02/skos/core#historyNote" /> <!-- http://www.w3.org/2004/02/skos/core#notation --> <owl:DatatypeProperty rdf:about="http://www.w3.org/2004/02/skos/core#notation" /> <!-- http://www.w3.org/2004/02/skos/core#prefLabel --> <owl:DatatypeProperty rdf:about="http://www.w3.org/2004/02/skos/core#prefLabel" /> <!-- Classes --> <!-- http://www.w3.org/2002/07/owl#Thing --> <owl:Class rdf:about="http://www.w3.org/2002/07/owl#Thing" /> <!-- http://www.w3.org/2004/02/skos/core#Concept --> <owl:Class rdf:about="http://www.w3.org/2004/02/skos/core#Concept" /> <!-- http://www.w3.org/2004/02/skos/core#ConceptScheme --> <owl:Class rdf:about="http://www.w3.org/2004/02/skos/core#ConceptScheme" /> <!-- Individuals --> </rdf:RDF></nsmap> <!-- Generated by the Arelle(r) http://arelle.org --> ''') from arelle.ModelObjectFactory import parser parser, parserLookupName, parserLookupClass = parser(dts, None) from lxml import etree xmlDocument = etree.parse(file, parser=parser, base_url=skosFile) file.close() xmlRootElement = xmlDocument.getroot() #xmlDocument.getroot().init(self) ## is this needed ?? for rdfElement in xmlDocument.iter( tag="{http://www.w3.org/1999/02/22-rdf-syntax-ns#}RDF"): break numSchemes = 0 numConcepts = 0 # use presentation relationships for broader and narrower concepts relationshipSet = dts.relationshipSet(XbrlConst.parentChild) def conceptUri(concept): return concept.qname.namespaceURI + "#" + concept.qname.localName def namespaceUri(qname): return qname.namespaceURI + "#" + qname.prefix priorSchemeSibling = None schemeNamespaces = set() dts.modelManager.showStatus("setting SKOS concepts from XBRL concepts") for qn, concept in sorted(dts.qnameConcepts.items(), key=lambda item: str(item[0])): if concept.modelDocument.targetNamespace not in (XbrlConst.xbrli, XbrlConst.link, XbrlConst.xlink, XbrlConst.xl, XbrlConst.xbrldt): if qn.namespaceURI not in schemeNamespaces: # add conceptScheme numSchemes += 1 skosElt = etree.Element( "{http://www.w3.org/2004/02/skos/core#}ConceptScheme") skosElt.set( "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}about", namespaceUri(qn)) elt = etree.SubElement( skosElt, "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}type") elt.set( "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource", "http://www.w3.org/2002/07/owl#Thing") elt = etree.SubElement( skosElt, "{http://www.w3.org/2004/02/skos/core#}notation") elt.text = str(qn.prefix) schemeNamespaces.add(qn.namespaceURI) if priorSchemeSibling is not None: priorSchemeSibling.addnext(skosElt) else: rdfElement.append(skosElt) priorSchemeSibling = skosElt numConcepts += 1 skosElt = etree.SubElement( rdfElement, "{http://www.w3.org/2004/02/skos/core#}Concept") skosElt.set( "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}about", conceptUri(concept)) elt = etree.SubElement( skosElt, "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}type") elt.set( "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource", "http://www.w3.org/2002/07/owl#Thing") elt = etree.SubElement( skosElt, "{http://www.w3.org/2004/02/skos/core#}notation") elt.text = str(concept.qname) definition = concept.label( preferredLabel=XbrlConst.documentationLabel, lang="en", strip=True, fallbackToQname=False) if definition: elt = etree.SubElement( skosElt, "{http://www.w3.org/2004/02/skos/core#}definition") elt.text = definition else: # if no definition, look for any references references = viewReferences(concept) if references: elt = etree.SubElement( skosElt, "{http://www.w3.org/2004/02/skos/core#}definition") elt.text = references linkedReferenceURI = referenceURI(concept) if linkedReferenceURI: # link to reference elt = etree.SubElement( skosElt, "{http://www.w3.org/2004/02/skos/core#}definition") elt.text = linkedReferenceURI labelsRelationshipSet = dts.relationshipSet( XbrlConst.conceptLabel) if labelsRelationshipSet: for modelLabelRel in labelsRelationshipSet.fromModelObject( concept): label = modelLabelRel.toModelObject if label.role == XbrlConst.standardLabel: elt = etree.SubElement( skosElt, "{http://www.w3.org/2004/02/skos/core#}prefLabel" ) elt.set( "{http://www.w3.org/XML/1998/namespace}lang", label.xmlLang) elt.text = label.text.strip() for rel in relationshipSet.fromModelObject( concept): # narrower elt = etree.SubElement( skosElt, "{http://www.w3.org/2004/02/skos/core#}narrower") elt.set( "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource", conceptUri(rel.toModelObject)) for rel in relationshipSet.toModelObject(concept): # broader elt = etree.SubElement( skosElt, "{http://www.w3.org/2004/02/skos/core#}broader") elt.set( "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource", conceptUri(rel.fromModelObject)) elt = etree.SubElement( skosElt, "{http://www.w3.org/2004/02/skos/core#}inScheme") elt.set( "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}resource", namespaceUri(qn)) dts.modelManager.showStatus("saving SKOS file") fh = open(skosFile, "w", encoding="utf-8") XmlUtil.writexml(fh, xmlDocument, encoding="utf-8") fh.close() dts.info( "info:saveSKOS", _("SKOS of %(entryFile)s has %(numberOfConcepts)s concepts in SKOS RDF file %(skosOutputFile)s." ), modelObject=dts, entryFile=dts.uri, numberOfConcepts=numConcepts, skosOutputFile=skosFile) dts.modelManager.showStatus("ready", 3000) except Exception as ex: dts.error("exception", _("SKOS generation exception: %(error)s"), error=ex, modelXbrl=dts, exc_info=True)
def generateUpdatedTableLB(dts, updatedTableLinkbaseFile): import os, io from arelle import XmlUtil, XbrlConst from arelle.ViewUtil import viewReferences, referenceURI from arelle.ModelRenderingObject import ModelEuAxisCoord if dts.fileSource.isArchive: dts.error( "genTblLB:outFileIsArchive", _("Updated Table Linkbase file cannot be an archive: %(tableLBOutputFile)s." ), modelObject=dts, tableLBOutputFile=updatedTableLinkbaseFile) return tblAxisRelSet = dts.relationshipSet(XbrlConst.euTableAxis) axisMbrRelSet = dts.relationshipSet(XbrlConst.euAxisMember) if len(tblAxisRelSet.modelRelationships) == 0: dts.error( "genTblLB:noInputTables", _("DTS does not contain Eurofiling 2010 tables and axes: %(entryFile)s." ), modelObject=dts, entryFile=dts.uri) return file = io.StringIO(''' <nsmap> <link:linkbase xmlns:label="http://xbrl.org/2008/label" xmlns:gen="http://xbrl.org/2008/generic" xmlns:df="http://xbrl.org/2008/filter/dimension" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:reference="http://xbrl.org/2008/reference" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:link="http://www.xbrl.org/2003/linkbase" xmlns:table="http://xbrl.org/2011/table" xmlns:formula="http://xbrl.org/2008/formula" xsi:schemaLocation=" http://www.xbrl.org/2003/linkbase http://www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd http://xbrl.org/2008/generic http://www.xbrl.org/2008/generic-link.xsd http://xbrl.org/2008/reference http://www.xbrl.org/2008/generic-reference.xsd http://xbrl.org/2008/label http://www.xbrl.org/2008/generic-label.xsd http://xbrl.org/2011/table http://www.xbrl.org/2011/table.xsd http://xbrl.org/2008/filter/dimension http://www.xbrl.org/2008/dimension-filter.xsd"> <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2011/table-filter" xlink:type="simple" xlink:href="http://www.xbrl.org/2011/table.xsd#table-filter"/> <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2011/table-axis" xlink:type="simple" xlink:href="http://www.xbrl.org/2011/table.xsd#table-axis"/> <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2011/axis-subtree" xlink:type="simple" xlink:href="http://www.xbrl.org/2011/table.xsd#axis-subtree"/> <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2011/axis-filter" xlink:type="simple" xlink:href="http://www.xbrl.org/2011/filter-axis.xsd#axis-filter"/> </link:linkbase> </nsmap> <!-- Generated by Arelle(r) http://arelle.org --> ''') from arelle.ModelObjectFactory import parser parser, parserLookupName, parserLookupClass = parser(dts, None) from lxml import etree xmlDocument = etree.parse(file, parser=parser, base_url=updatedTableLinkbaseFile) file.close() nsmapElt = xmlDocument.getroot() #xmlDocument.getroot().init(self) ## is this needed ?? for lbElement in xmlDocument.iter( tag="{http://www.xbrl.org/2003/linkbase}linkbase"): break class DocObj: # fake ModelDocument for namespaces def __init__(self): self.xmlRootElement = lbElement self.xmlDocument = xmlDocument docObj = DocObj() numELRs = 0 numTables = 0 def copyAttrs(fromElt, toElt, attrTags): for attr in attrTags: if fromElt.get(attr): toElt.set(attr, fromElt.get(attr)) def generateTable(newLinkElt, newTblElt, srcTblElt, tblAxisRelSet, axisMbrRelSet, visited): if srcTblElt is not None: for rel in tblAxisRelSet.fromModelObject(srcTblElt): srcAxisElt = rel.toModelObject if isinstance(srcAxisElt, ModelEuAxisCoord): visited.add(srcAxisElt) newAxisElt = etree.SubElement( newLinkElt, "{http://xbrl.org/2011/table}ruleAxis") copyAttrs(srcAxisElt, newAxisElt, ("id", "{http://www.w3.org/1999/xlink}type", "{http://www.w3.org/1999/xlink}label")) newAxisElt.set("abstract", "true") # always true on root element newArcElt = etree.SubElement( newLinkElt, "{http://xbrl.org/2011/table}axisArc") copyAttrs(rel, newArcElt, ("id", "{http://www.w3.org/1999/xlink}type", "{http://www.w3.org/1999/xlink}from", "{http://www.w3.org/1999/xlink}to", "order")) newArcElt.set("{http://www.w3.org/1999/xlink}arcrole", XbrlConst.tableBreakdown) newArcElt.set("axisDisposition", rel.axisDisposition) generateAxis(newLinkElt, newAxisElt, srcAxisElt, axisMbrRelSet, visited) visited.discard(srcAxisElt) def generateAxis(newLinkElt, newAxisParentElt, srcAxisElt, axisMbrRelSet, visited): for rel in axisMbrRelSet.fromModelObject(srcAxisElt): tgtAxisElt = rel.toModelObject if isinstance(tgtAxisElt, ModelEuAxisCoord) and tgtAxisElt not in visited: visited.add(tgtAxisElt) newAxisElt = etree.SubElement( newLinkElt, "{http://xbrl.org/2011/table}ruleAxis") copyAttrs( tgtAxisElt, newAxisElt, ("id", "abstract", "{http://www.w3.org/1999/xlink}type", "{http://www.w3.org/1999/xlink}label")) if tgtAxisElt.primaryItemQname: newRuleElt = etree.SubElement( newAxisElt, "{http://xbrl.org/2008/formula}concept") newQnameElt = etree.SubElement( newRuleElt, "{http://xbrl.org/2008/formula}qname") newQnameElt.text = XmlUtil.addQnameValue( docObj, tgtAxisElt.primaryItemQname) for dimQname, memQname in tgtAxisElt.explicitDims: newRuleElt = etree.SubElement( newAxisElt, "{http://xbrl.org/2008/formula}explicitDimension") newRuleElt.set("dimension", XmlUtil.addQnameValue(docObj, dimQname)) newMbrElt = etree.SubElement( newRuleElt, "{http://xbrl.org/2008/formula}member") newQnameElt = etree.SubElement( newMbrElt, "{http://xbrl.org/2008/formula}qname") newQnameElt.text = XmlUtil.addQnameValue(docObj, memQname) newArcElt = etree.SubElement( newLinkElt, "{http://xbrl.org/2011/table}axisArc") copyAttrs(rel, newArcElt, ("id", "{http://www.w3.org/1999/xlink}type", "{http://www.w3.org/1999/xlink}from", "{http://www.w3.org/1999/xlink}to", "order")) newArcElt.set("{http://www.w3.org/1999/xlink}arcrole", XbrlConst.tableAxisSubtree) generateAxis(newLinkElt, newAxisElt, tgtAxisElt, axisMbrRelSet, visited) visited.discard(tgtAxisElt) # sort URIs linkroleUris = sorted( [linkroleUri for linkroleUri in tblAxisRelSet.linkRoleUris]) firstNewLinkElt = None roleRefUris = set() for linkroleUri in linkroleUris: numELRs += 1 newLinkElt = etree.SubElement(lbElement, "{http://xbrl.org/2008/generic}link") newLinkElt.set("{http://www.w3.org/1999/xlink}type", "extended") newLinkElt.set("{http://www.w3.org/1999/xlink}role", linkroleUri) if firstNewLinkElt is None: firstNewLinkElt = newLinkElt # To do: add roleRef if needed tblAxisRelSet = dts.relationshipSet(XbrlConst.euTableAxis, linkroleUri) axisMbrRelSet = dts.relationshipSet(XbrlConst.euAxisMember, linkroleUri) for srcTblElt in tblAxisRelSet.rootConcepts: if srcTblElt.tag == "{http://www.eurofiling.info/2010/rendering}table": numTables += 1 newTblElt = etree.SubElement( newLinkElt, "{http://xbrl.org/2011/table}table") newTblElt.set("aspectModel", "dimensional") copyAttrs(srcTblElt, newTblElt, ("id", "{http://www.w3.org/1999/xlink}type", "{http://www.w3.org/1999/xlink}label")) generateTable(newLinkElt, newTblElt, srcTblElt, tblAxisRelSet, axisMbrRelSet, set()) if linkroleUri not in roleRefUris: srcRoleRefElt = XmlUtil.descendant(srcTblElt.getroottree(), XbrlConst.link, "roleRef", "roleURI", linkroleUri) if srcRoleRefElt is not None: roleRefUris.add(linkroleUri) newRoleRefElt = etree.Element( "{http://www.xbrl.org/2003/linkbase}roleRef") copyAttrs( srcRoleRefElt, newRoleRefElt, ("roleURI", "{http://www.w3.org/1999/xlink}type", "{http://www.w3.org/1999/xlink}href")) firstNewLinkElt.addprevious(newRoleRefElt) fh = open(updatedTableLinkbaseFile, "w", encoding="utf-8") XmlUtil.writexml(fh, xmlDocument, encoding="utf-8") fh.close() dts.info( "info:updateTableLinkbase", _("Updated Table Linkbase of %(entryFile)s has %(numberOfLinkroles)s linkroles, %(numberOfTables)s tables in file %(tableLBOutputFile)s." ), modelObject=dts, entryFile=dts.uri, numberOfLinkroles=numELRs, numberOfTables=numTables, tableLBOutputFile=updatedTableLinkbaseFile)
try: if fact.concept.periodType: fact.set(u"{http://www.xbrl.org/2003/ptv}periodType", fact.concept.periodType) if fact.concept.balance: fact.set(u"{http://www.xbrl.org/2003/ptv}balance", fact.concept.balance) if fact.isNumeric and not fact.isNil: fact.set(u"{http://www.xbrl.org/2003/ptv}decimals", unicode(inferredDecimals(fact))) fact.set(u"{http://www.xbrl.org/2003/ptv}precision", unicode(inferredPrecision(fact))) numFacts += 1 except Exception, err: dts.error(u"saveInfoset.exception", _(u"Facts exception %(fact)s %(value)s %(error)s."), modelObject=fact, fact=fact.qname, value=fact.effectiveValue, error = err) fh = open(instanceInfosetFile, u"w", encoding=u"utf-8") XmlUtil.writexml(fh, dts.modelDocument.xmlDocument, encoding=u"utf-8") fh.close() dts.info(u"info:saveInstanceInfoset", _(u"Instance infoset of %(entryFile)s has %(numberOfFacts)s facts in infoset file %(infosetOutputFile)s."), modelObject=dts, entryFile=dts.uri, numberOfFacts=numFacts, infosetOutputFile=instanceInfosetFile) def saveInstanceInfosetMenuEntender(cntlr, menu): # Extend menu with an item for the save infoset plugin menu.add_command(label=u"Save infoset", underline=0, command=lambda: saveInstanceInfosetMenuCommand(cntlr) ) def saveInstanceInfosetMenuCommand(cntlr): # save Infoset menu item has been invoked
def runFromExcel(self, options): #testGenFileName = options.excelfilename testGenFileName = r"C:\Users\Herm Fischer\Documents\mvsl\projects\XBRL.org\conformance-versioning\trunk\versioningReport\conf\creation-index.xls" testGenDir = os.path.dirname(testGenFileName) schemaDir = os.path.dirname(testGenDir) + os.sep + "schema" timeNow = XmlUtil.dateunionValue(datetime.datetime.now()) if options.testfiledate: today = options.testfiledate else: today = XmlUtil.dateunionValue(datetime.date.today()) startedAt = time.time() LogHandler(self) # start logger self.logMessages = [] logMessagesFile = testGenDir + os.sep + 'log-generation-messages.txt' modelTestcases = ModelXbrl.create(self.modelManager, url=testGenFileName, isEntry=True) testcaseIndexBook = xlrd.open_workbook(testGenFileName) testcaseIndexSheet = testcaseIndexBook.sheet_by_index(0) self.addToLog( _("[info] xls loaded in {0:.2} secs at {1}").format( time.time() - startedAt, timeNow)) # start index file indexFiles = [ testGenDir + os.sep + 'creation-testcases-index.xml', testGenDir + os.sep + 'consumption-testcases-index.xml' ] indexDocs = [] testcasesElements = [] for purpose in ("Creation", "Consumption"): file = io.StringIO( #'<?xml version="1.0" encoding="UTF-8"?>' '<!-- XBRL Versioning 1.0 {0} Tests -->' '<!-- Copyright 2011 XBRL International. All Rights Reserved. -->' '<?xml-stylesheet type="text/xsl" href="infrastructure/testcases-index.xsl"?>' '<testcases name="XBRL Versioning 1.0 {0} Tests" ' ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' ' xsi:noNamespaceSchemaLocation="infrastructure/testcases-index.xsd">' '</testcases>'.format(purpose, today)) doc = etree.parse(file) file.close() indexDocs.append(doc) testcasesElements.append(doc.getroot()) priorTestcasesDir = None testcaseFiles = None testcaseDocs = None for iRow in range(1, testcaseIndexSheet.nrows): try: row = testcaseIndexSheet.row(iRow) if (row[0].ctype == xlrd.XL_CELL_EMPTY or # must have directory row[1].ctype == xlrd.XL_CELL_EMPTY or # from row[2].ctype == xlrd.XL_CELL_EMPTY): # to continue testDir = row[0].value uriFrom = row[1].value uriTo = row[2].value overrideReport = row[3].value description = row[4].value if description is None or len(description) == 0: continue # test not ready to run assignment = row[5].value expectedEvents = row[ 6].value # comma space separated if multiple note = row[7].value useCase = row[8].value base = os.path.join(os.path.dirname(testGenFileName), testDir) + os.sep self.addToLog(_("[info] testcase uriFrom {0}").format(uriFrom)) if uriFrom and uriTo and assignment.lower() not in ( "n.a.", "error") and expectedEvents != "N.A.": modelDTSfrom = modelDTSto = None for URIs, msg, isFrom in ((uriFrom, _("loading from DTS"), True), (uriTo, _("loading to DTS"), False)): if ',' not in URIs: modelDTS = ModelXbrl.load(self.modelManager, URIs, msg, base=base) else: modelDTS = ModelXbrl.create( self.modelManager, ModelDocument.Type.DTSENTRIES, self.webCache.normalizeUrl( URIs.replace(", ", "_") + ".dts", base), isEntry=True) DTSdoc = modelDTS.modelDocument DTSdoc.inDTS = True for uri in URIs.split(','): doc = ModelDocument.load(modelDTS, uri.strip(), base=base) if doc is not None: DTSdoc.referencesDocument[ doc] = "import" #fake import doc.inDTS = True if isFrom: modelDTSfrom = modelDTS else: modelDTSto = modelDTS if modelDTSfrom is not None and modelDTSto is not None: # generate differences report reportUri = uriFrom.partition(',')[0] # first file reportDir = os.path.dirname(reportUri) if reportDir: reportDir += os.sep reportName = os.path.basename(reportUri).replace( "from.xsd", "report.xml") reportFile = reportDir + "out" + os.sep + reportName #reportFile = reportDir + "report" + os.sep + reportName reportFullPath = self.webCache.normalizeUrl( reportFile, base) testcasesDir = os.path.dirname( os.path.dirname(reportFullPath)) if testcasesDir != priorTestcasesDir: # close prior report if priorTestcasesDir: for i, testcaseFile in enumerate( testcaseFiles): with open(testcaseFile, "w", encoding="utf-8") as fh: XmlUtil.writexml(fh, testcaseDocs[i], encoding="utf-8") testcaseName = os.path.basename(testcasesDir) testcaseFiles = [ testcasesDir + os.sep + testcaseName + "-creation-testcase.xml", testcasesDir + os.sep + testcaseName + "-consumption-testcase.xml" ] for i, testcaseFile in enumerate(testcaseFiles): etree.SubElement( testcasesElements[i], "testcase", attrib={ "uri": testcaseFile[len(testGenDir) + 1:].replace("\\", "/") }) # start testcase file testcaseDocs = [] testcaseElements = [] testcaseNumber = testcaseName[0:4] if testcaseNumber.isnumeric(): testcaseNumberElement = "<number>{0}</number>".format( testcaseNumber) testcaseName = testcaseName[5:] else: testcaseNumberElement = "" testDirSegments = testDir.split('/') if len(testDirSegments ) >= 2 and '-' in testDirSegments[1]: testedModule = testDirSegments[1][ testDirSegments[1].index('-') + 1:] else: testedModule = '' for purpose in ("Creation", "Consumption"): file = io.StringIO( #'<?xml version="1.0" encoding="UTF-8"?>' '<!-- Copyright 2011 XBRL International. All Rights Reserved. -->' '<?xml-stylesheet type="text/xsl" href="../../../infrastructure/test.xsl"?>' '<testcase ' ' xmlns="http://xbrl.org/2008/conformance"' ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' ' xsi:schemaLocation="http://xbrl.org/2008/conformance ../../../infrastructure/test.xsd">' '<creator>' '<name>Roland Hommes</name>' '<email>[email protected]</email>' '</creator>' '{0}' '<name>{1}</name>' # '<description>{0}</description>' '<reference>' '{2}' '{3}' '</reference>' '</testcase>'.format( testcaseNumberElement, testcaseName, '<name>{0}</name>'.format(testedModule) if testedModule else '', '<id>{0}</id>'.format(useCase) if useCase else '')) doc = etree.parse(file) file.close() testcaseDocs.append(doc) testcaseElements.append(doc.getroot()) priorTestcasesDir = testcasesDir variationSeq = 1 try: os.makedirs(os.path.dirname(reportFullPath)) except WindowsError: pass # dir already exists modelVersReport = ModelVersReport.ModelVersReport( modelTestcases) modelVersReport.diffDTSes(reportFullPath, modelDTSfrom, modelDTSto, assignment=assignment, schemaDir=schemaDir) # check for expected elements if expectedEvents: for expectedEvent in expectedEvents.split(","): if expectedEvent not in ("No change", "N.A."): prefix, sep, localName = expectedEvent.partition( ':') if sep and len( modelVersReport.xmlDocument. findall('//{{{0}}}{1}'.format( XbrlConst.verPrefixNS.get( prefix), localName))) == 0: modelTestcases.warning( "warning", "Generated test case %(reportName)s missing expected event %(event)s", reportName=reportName, event=expectedEvent) modelVersReport.close() uriFromParts = uriFrom.split('_') if len(uriFromParts) >= 2: variationId = uriFromParts[1] else: variationId = "_{0:02n}".format(variationSeq) for i, testcaseElt in enumerate(testcaseElements): variationElement = etree.SubElement( testcaseElt, "{http://xbrl.org/2008/conformance}variation", attrib={"id": variationId}) nameElement = etree.SubElement( variationElement, "{http://xbrl.org/2008/conformance}description" ) nameElement.text = description ''' (removed per RH 2011/10/04 if note: paramElement = etree.SubElement(variationElement, "{http://xbrl.org/2008/conformance}description") paramElement.text = "Note: " + note if useCase: paramElement = etree.SubElement(variationElement, "{http://xbrl.org/2008/conformance}reference") paramElement.set("specification", "versioning-requirements") paramElement.set("useCase", useCase) ''' dataElement = etree.SubElement( variationElement, "{http://xbrl.org/2008/conformance}data") if i == 0: # result is report if expectedEvents: paramElement = etree.SubElement( dataElement, "{http://xbrl.org/2008/conformance}parameter", attrib={ "name": "expectedEvent", "value": expectedEvents.replace(',', ' ') }, nsmap={ "conf": "http://xbrl.org/2008/conformance", None: "" }) if assignment: paramElement = etree.SubElement( dataElement, "{http://xbrl.org/2008/conformance}parameter", attrib={ "name": "assignment", "value": assignment }, nsmap={ "conf": "http://xbrl.org/2008/conformance", None: "" }) for schemaURIs, dtsAttr in ((uriFrom, "from"), (uriTo, "to")): for schemaURI in schemaURIs.split(","): schemaElement = etree.SubElement( dataElement, "{http://xbrl.org/2008/conformance}schema" ) schemaElement.set("dts", dtsAttr) if i == 0: schemaElement.set( "readMeFirst", "true") schemaElement.text = os.path.basename( schemaURI.strip()) resultElement = etree.SubElement( variationElement, "{http://xbrl.org/2008/conformance}result") reportElement = etree.SubElement( resultElement if i == 0 else dataElement, "{http://xbrl.org/2008/conformance}versioningReport" ) if i == 1: reportElement.set("readMeFirst", "true") reportElement.text = "report/" + reportName variationSeq += 1 except Exception as err: modelTestcases.error( "exception", _("Exception: %(error)s, Excel row: %(excelRow)s"), error=err, excelRow=iRow, exc_info=True) # add tests-error-code index files to consumption for testcaseFile in self.testcaseFiles(testGenDir + os.sep + "tests-error-code"): etree.SubElement(testcasesElements[1], "testcase", attrib={ "uri": testcaseFile[len(testGenDir) + 1:].replace( "\\", "/") }) with open(logMessagesFile, "w") as fh: fh.writelines(self.logMessages) if priorTestcasesDir: for i, testcaseFile in enumerate(testcaseFiles): with open(testcaseFile, "w", encoding="utf-8") as fh: XmlUtil.writexml(fh, testcaseDocs[i], encoding="utf-8") for i, indexFile in enumerate(indexFiles): with open(indexFile, "w", encoding="utf-8") as fh: XmlUtil.writexml(fh, indexDocs[i], encoding="utf-8")
def view(self, xmlDoc): fh = io.StringIO() XmlUtil.writexml(fh, xmlDoc, encoding="utf-8") for line in fh.getvalue().split("\n"): self.listBox.insert(END, line) fh.close()
def generateUpdatedTableLB(dts, updatedTableLinkbaseFile): import os, io from arelle import XmlUtil, XbrlConst from arelle.ViewUtil import viewReferences, referenceURI from arelle.ModelRenderingObject import ModelEuAxisCoord if dts.fileSource.isArchive: dts.error("genTblLB:outFileIsArchive", _("Updated Table Linkbase file cannot be an archive: %(tableLBOutputFile)s."), modelObject=dts, tableLBOutputFile=updatedTableLinkbaseFile) return tblAxisRelSet = dts.relationshipSet(XbrlConst.euTableAxis) axisMbrRelSet = dts.relationshipSet(XbrlConst.euAxisMember) if len(tblAxisRelSet.modelRelationships) == 0: dts.error("genTblLB:noInputTables", _("DTS does not contain Eurofiling 2010 tables and axes: %(entryFile)s."), modelObject=dts, entryFile=dts.uri) return file = io.StringIO(''' <nsmap> <link:linkbase xmlns:label="http://xbrl.org/2008/label" xmlns:gen="http://xbrl.org/2008/generic" xmlns:df="http://xbrl.org/2008/filter/dimension" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:reference="http://xbrl.org/2008/reference" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:link="http://www.xbrl.org/2003/linkbase" xmlns:table="http://xbrl.org/2011/table" xmlns:formula="http://xbrl.org/2008/formula" xsi:schemaLocation=" http://www.xbrl.org/2003/linkbase http://www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd http://xbrl.org/2008/generic http://www.xbrl.org/2008/generic-link.xsd http://xbrl.org/2008/reference http://www.xbrl.org/2008/generic-reference.xsd http://xbrl.org/2008/label http://www.xbrl.org/2008/generic-label.xsd http://xbrl.org/2011/table http://www.xbrl.org/2011/table.xsd http://xbrl.org/2008/filter/dimension http://www.xbrl.org/2008/dimension-filter.xsd"> <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2011/table-filter" xlink:type="simple" xlink:href="http://www.xbrl.org/2011/table.xsd#table-filter"/> <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2011/table-axis" xlink:type="simple" xlink:href="http://www.xbrl.org/2011/table.xsd#table-axis"/> <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2011/axis-subtree" xlink:type="simple" xlink:href="http://www.xbrl.org/2011/table.xsd#axis-subtree"/> <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2011/axis-filter" xlink:type="simple" xlink:href="http://www.xbrl.org/2011/filter-axis.xsd#axis-filter"/> </link:linkbase> </nsmap> <!-- Generated by Arelle(r) http://arelle.org --> ''' ) from arelle.ModelObjectFactory import parser parser, parserLookupName, parserLookupClass = parser(dts,None) from lxml import etree xmlDocument = etree.parse(file,parser=parser,base_url=updatedTableLinkbaseFile) file.close() nsmapElt = xmlDocument.getroot() #xmlDocument.getroot().init(self) ## is this needed ?? for lbElement in xmlDocument.iter(tag="{http://www.xbrl.org/2003/linkbase}linkbase"): break class DocObj: # fake ModelDocument for namespaces def __init__(self): self.xmlRootElement = lbElement self.xmlDocument = xmlDocument docObj = DocObj() numELRs = 0 numTables = 0 def copyAttrs(fromElt, toElt, attrTags): for attr in attrTags: if fromElt.get(attr): toElt.set(attr, fromElt.get(attr)) def generateTable(newLinkElt, newTblElt, srcTblElt, tblAxisRelSet, axisMbrRelSet, visited): if srcTblElt is not None: for rel in tblAxisRelSet.fromModelObject(srcTblElt): srcAxisElt = rel.toModelObject if isinstance(srcAxisElt, ModelEuAxisCoord): visited.add(srcAxisElt) newAxisElt = etree.SubElement(newLinkElt, "{http://xbrl.org/2011/table}ruleAxis") copyAttrs(srcAxisElt, newAxisElt, ("id", "{http://www.w3.org/1999/xlink}type", "{http://www.w3.org/1999/xlink}label")) newAxisElt.set("abstract", "true") # always true on root element newArcElt = etree.SubElement(newLinkElt, "{http://xbrl.org/2011/table}axisArc") copyAttrs(rel, newArcElt, ("id", "{http://www.w3.org/1999/xlink}type", "{http://www.w3.org/1999/xlink}from", "{http://www.w3.org/1999/xlink}to", "order")) newArcElt.set("{http://www.w3.org/1999/xlink}arcrole", XbrlConst.tableBreakdown) newArcElt.set("axisDisposition", rel.axisDisposition) generateAxis(newLinkElt, newAxisElt, srcAxisElt, axisMbrRelSet, visited) visited.discard(srcAxisElt) def generateAxis(newLinkElt, newAxisParentElt, srcAxisElt, axisMbrRelSet, visited): for rel in axisMbrRelSet.fromModelObject(srcAxisElt): tgtAxisElt = rel.toModelObject if isinstance(tgtAxisElt, ModelEuAxisCoord) and tgtAxisElt not in visited: visited.add(tgtAxisElt) newAxisElt = etree.SubElement(newLinkElt, "{http://xbrl.org/2011/table}ruleAxis") copyAttrs(tgtAxisElt, newAxisElt, ("id", "abstract", "{http://www.w3.org/1999/xlink}type", "{http://www.w3.org/1999/xlink}label")) if tgtAxisElt.primaryItemQname: newRuleElt = etree.SubElement(newAxisElt, "{http://xbrl.org/2008/formula}concept") newQnameElt = etree.SubElement(newRuleElt, "{http://xbrl.org/2008/formula}qname") newQnameElt.text = XmlUtil.addQnameValue(docObj, tgtAxisElt.primaryItemQname) for dimQname, memQname in tgtAxisElt.explicitDims: newRuleElt = etree.SubElement(newAxisElt, "{http://xbrl.org/2008/formula}explicitDimension") newRuleElt.set("dimension", XmlUtil.addQnameValue(docObj, dimQname)) newMbrElt = etree.SubElement(newRuleElt, "{http://xbrl.org/2008/formula}member") newQnameElt = etree.SubElement(newMbrElt, "{http://xbrl.org/2008/formula}qname") newQnameElt.text = XmlUtil.addQnameValue(docObj, memQname) newArcElt = etree.SubElement(newLinkElt, "{http://xbrl.org/2011/table}axisArc") copyAttrs(rel, newArcElt, ("id", "{http://www.w3.org/1999/xlink}type", "{http://www.w3.org/1999/xlink}from", "{http://www.w3.org/1999/xlink}to", "order")) newArcElt.set("{http://www.w3.org/1999/xlink}arcrole", XbrlConst.tableAxisSubtree) generateAxis(newLinkElt, newAxisElt, tgtAxisElt, axisMbrRelSet, visited) visited.discard(tgtAxisElt) # sort URIs linkroleUris = sorted([linkroleUri for linkroleUri in tblAxisRelSet.linkRoleUris]) firstNewLinkElt = None roleRefUris = set() for linkroleUri in linkroleUris: numELRs += 1 newLinkElt = etree.SubElement(lbElement, "{http://xbrl.org/2008/generic}link") newLinkElt.set("{http://www.w3.org/1999/xlink}type", "extended") newLinkElt.set("{http://www.w3.org/1999/xlink}role", linkroleUri) if firstNewLinkElt is None: firstNewLinkElt = newLinkElt # To do: add roleRef if needed tblAxisRelSet = dts.relationshipSet(XbrlConst.euTableAxis, linkroleUri) axisMbrRelSet = dts.relationshipSet(XbrlConst.euAxisMember, linkroleUri) for srcTblElt in tblAxisRelSet.rootConcepts: if srcTblElt.tag == "{http://www.eurofiling.info/2010/rendering}table": numTables += 1 newTblElt = etree.SubElement(newLinkElt, "{http://xbrl.org/2011/table}table") newTblElt.set("aspectModel", "dimensional") copyAttrs(srcTblElt, newTblElt, ("id", "{http://www.w3.org/1999/xlink}type", "{http://www.w3.org/1999/xlink}label")) generateTable(newLinkElt, newTblElt, srcTblElt, tblAxisRelSet, axisMbrRelSet, set()) if linkroleUri not in roleRefUris: srcRoleRefElt = XmlUtil.descendant(srcTblElt.getroottree(), XbrlConst.link, "roleRef", "roleURI", linkroleUri) if srcRoleRefElt is not None: roleRefUris.add(linkroleUri) newRoleRefElt = etree.Element("{http://www.xbrl.org/2003/linkbase}roleRef") copyAttrs(srcRoleRefElt, newRoleRefElt, ("roleURI", "{http://www.w3.org/1999/xlink}type", "{http://www.w3.org/1999/xlink}href")) firstNewLinkElt.addprevious(newRoleRefElt) fh = open(updatedTableLinkbaseFile, "w", encoding="utf-8") XmlUtil.writexml(fh, xmlDocument, encoding="utf-8") fh.close() dts.info("info:updateTableLinkbase", _("Updated Table Linkbase of %(entryFile)s has %(numberOfLinkroles)s linkroles, %(numberOfTables)s tables in file %(tableLBOutputFile)s."), modelObject=dts, entryFile=dts.uri, numberOfLinkroles=numELRs, numberOfTables=numTables, tableLBOutputFile=updatedTableLinkbaseFile)
def generateFormulaLB(cntlr, sphinxFiles, generatedSphinxFormulasDirectory): if sys.version[0] >= '3': from arelle.pyparsing.pyparsing_py3 import lineno else: from pyparsing import lineno from .SphinxContext import SphinxContext from .SphinxValidator import validate msgFile = None sourceString = None # logMessage operates without an instance document or ModelXbrl, so it simulates log function def logMessage(severity, code, text, **kwargs): if "sourceFileLines" in kwargs: # use pairs of file and line number fileLines = ", ".join((file + (" " + str(line)) if line else "") for file, line in kwargs["sourceFileLines"]) elif "sourceFileLine" in kwargs: file, line in kwargs["sourceFileLine"] fileLines = file + (" " + str(line)) if line else "" else: fileLines = "" if not fileLines: fileLines = ", " + fileLines try: cntlr.addToLog("[{0}] {1}{2}".format(code, text % kwargs, fileLines)) except KeyError as err: cntlr.addToLog( "[{0}] {1}: Missing message parameter: {2}; {3}".format( code, text, err, fileLines)) from arelle import XmlUtil sc = SphinxContext(parse(cntlr, logMessage, sphinxFiles)) sc.logMessage = logMessage validate(logMessage, sc) assertionIDs = set() for prog in sc.sphinxProgs: sphinxFile = prog[0].fileName sphinxXmlns = { "xlink": 'http://www.w3.org/1999/xlink', "link": 'http://www.xbrl.org/2003/linkbase', "xbrli": 'http://www.xbrl.org/2003/instance', "generic": 'http://xbrl.org/2008/generic', "formula": 'http://xbrl.org/2008/formula', "validation": 'http://xbrl.org/2008/validation', "variable": 'http://xbrl.org/2008/variable', "label": 'http://xbrl.org/2008/label', "ca": 'http://xbrl.org/2008/assertion/consistency', "ea": 'http://xbrl.org/2008/assertion/existence', "va": 'http://xbrl.org/2008/assertion/value', "msg": 'http://xbrl.org/2010/message', "bf": 'http://xbrl.org/2008/filter/boolean', "cf": 'http://xbrl.org/2008/filter/concept', "df": 'http://xbrl.org/2008/filter/dimension', "gf": 'http://xbrl.org/2008/filter/general', "pf": 'http://xbrl.org/2008/filter/period', "uf": 'http://xbrl.org/2008/filter/unit', "xfi": 'http://www.xbrl.org/2008/function/instance', "xsi": 'http://www.w3.org/2001/XMLSchema-instance', "xs": 'http://www.w3.org/2001/XMLSchema', } for node in prog: if isinstance(node, astNamespaceDeclaration): sphinxXmlns[node.prefix] = node.namespace formulaFile = sphinxFile.rpartition(".")[0] + "-formula.xml" # save in generatedSphinxFormulasDirectory if specified and valid (exists) if generatedSphinxFormulasDirectory and os.path.isdir( generatedSphinxFormulasDirectory): formulaFile = os.path.join(generatedSphinxFormulasDirectory, os.path.basename(formulaFile)) xbrlLBfile = io.StringIO(''' <nsmap> <link:linkbase {0} xsi:schemaLocation="http://www.xbrl.org/2003/linkbase http://www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd" > <link:arcroleRef arcroleURI='http://xbrl.org/arcrole/2008/element-label' xlink:href='http://www.xbrl.org/2008/generic-label.xsd#element-label' xlink:type='simple'/> <link:arcroleRef arcroleURI='http://xbrl.org/arcrole/2008/variable-set' xlink:href='http://www.xbrl.org/2008/variable.xsd#variable-set' xlink:type='simple'/> <link:arcroleRef arcroleURI='http://xbrl.org/arcrole/2008/variable-filter' xlink:href='http://www.xbrl.org/2008/variable.xsd#variable-filter' xlink:type='simple'/> <link:arcroleRef arcroleURI='http://xbrl.org/arcrole/2008/variable-set-precondition' xlink:href='http://www.xbrl.org/2008/variable.xsd#variable-set-precondition' xlink:type='simple'/> <link:arcroleRef arcroleURI='http://xbrl.org/arcrole/2008/consistency-assertion-formula' xlink:href='http://www.xbrl.org/2008/consistency-assertion.xsd#consistency-assertion-formula' xlink:type='simple'/> <link:roleRef roleURI='http://www.xbrl.org/2008/role/link' xlink:href='http://www.xbrl.org/2008/generic-link.xsd#standard-link-role' xlink:type='simple'/> <link:roleRef roleURI='http://www.xbrl.org/2008/role/label' xlink:href='http://www.xbrl.org/2008/generic-label.xsd#standard-label' xlink:type='simple'/> <link:roleRef roleURI="http://www.xbrl.org/2010/role/message" xlink:type="simple" xlink:href="http://www.xbrl.org/2010/generic-message.xsd#standard-message"/> <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2010/assertion-unsatisfied-message" xlink:type="simple" xlink:href="http://www.xbrl.org/2010/validation-message.xsd#assertion-unsatisfied-message"/> <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2010/assertion-satisfied-message" xlink:type="simple" xlink:href="http://www.xbrl.org/2010/validation-message.xsd#assertion-satisfied-message"/> <link:arcroleRef arcroleURI='http://xbrl.org/arcrole/2008/boolean-filter' xlink:href='http://www.xbrl.org/2008/boolean-filter.xsd#boolean-filter' xlink:type='simple'/> <generic:link xlink:type="extended" xlink:role="http://www.xbrl.org/2003/role/link"/> </link:linkbase> </nsmap> <!-- Generated by Arelle(r) http://arelle.org --> '''.format('\n'.join( "xmlns{0}='{1}'".format((":" + prefix) if prefix else "", namespace) for prefix, namespace in sphinxXmlns.items()))) msgFile = os.path.basename(formulaFile) xmlDocument = etree.parse(xbrlLBfile, base_url=formulaFile) xbrlLBfile.close() nsmapElt = xmlDocument.getroot() #xmlDocument.getroot().init(self) ## is this needed ?? for lbElement in xmlDocument.iter( tag="{http://www.xbrl.org/2003/linkbase}linkbase"): break for e in xmlDocument.iter(tag="{http://xbrl.org/2008/generic}link"): sc.genLinkElement = e break class DocObj: # fake ModelDocument for namespaces def __init__(self): self.xmlRootElement = lbElement self.xmlDocument = xmlDocument docObj = DocObj() numRules = 0 sc.generatedVarNbr = 1 sc.xpathCode = None sc.bindAsSequence = False sc.nodeXpathVarBindings = {} for node in prog: if isinstance(node, (astFormulaRule, astReportRule, astValidationRule)): # form unique ID sc.assertionID = node.name if sc.assertionID in assertionIDs: for suffixNumber in range(1, 10000): if sc.assertionID + str( suffixNumber) not in assertionIDs: sc.assertionID += str(suffixNumber) break assertionIDs.add(sc.assertionID) sc.assertionElt = etree.SubElement( sc.genLinkElement, "{http://xbrl.org/2008/assertion/value}valueAssertion", attrib={ "{http://www.w3.org/1999/xlink}type": "resource", "{http://www.w3.org/1999/xlink}label": sc.assertionID, "id": sc.assertionID, "aspectModel": "dimensional", "implicitFiltering": "true" }) sc.assertionVarNames = {"factVar_"} sc.generalVarNames = {} if isinstance(node, astFormulaRule): sc.assertionElt.set("test", xpathCode(node.expr, sc)) msgType = "assertion-unsatisfied-message" elif isinstance(node, astReportRule): sc.tags["value"] = node.expr # no test expression needed msgType = "assertion-unsatisfied-message" elif isinstance(node, astValidationRule): sc.assertionElt.set( "test", "not( " + xpathCode(node.expr, sc) + " )") msgType = "assertion-satisfied-message" genMessage(node.message, sc, msgType) sc.nodeXpathVarBindings.clear() with open(formulaFile, "w", encoding="utf-8") as fh: XmlUtil.writexml(fh, xmlDocument, encoding="utf-8") logMessage( "INFO", "info:compileSphinx", _("Compiled Sphinx of %(sphinxFile)s has %(numberRules)s tables in file %(formulaFile)s." ), sphinxFile=sphinxFiles, numberRules=numRules, formulaFile=formulaFile) logMessage = None sc.close() cntlr.showStatus( "Finshed sphinx files {0}".format(", ".join( os.path.basename(f) for f in sphinxFiles)), 5000)
def fileSave(self, *ignore): if self.modelManager.modelXbrl: if self.modelManager.modelXbrl.modelDocument.type == ModelDocument.Type.TESTCASESINDEX: filename = tkinter.filedialog.asksaveasfilename( title=_("arelle\u2122 - Save Test Results"), initialdir=os.path.dirname(self.modelManager.modelXbrl.modelDocument.uri), filetypes=[(_("CSV file"), "*.csv")], defaultextension=".csv", parent=self.parent) if not filename: return False try: ViewCsvTests.viewTests(self.modelManager.modelXbrl, filename) except (IOError, EnvironmentError) as err: tkinter.messagebox.showwarning(_("arelle\u2122 - Error"), _("Failed to save {0}:\n{1}").format( self.filename, err), parent=self.parent) return True elif self.modelManager.modelXbrl.formulaOutputInstance: filename = tkinter.filedialog.asksaveasfilename( title=_("arelle\u2122 - Save Formula Result Instance Document"), initialdir=os.path.dirname(self.modelManager.modelXbrl.modelDocument.uri), filetypes=[(_("XBRL output instance .xml"), "*.xml"), (_("XBRL output instance .xbrl"), "*.xbrl")], defaultextension=".xml", parent=self.parent) if not filename: return False try: from arelle import XmlUtil with open(filename, "w") as fh: XmlUtil.writexml(fh, self.modelManager.modelXbrl.formulaOutputInstance.modelDocument.xmlDocument, encoding="utf-8") self.addToLog(_("[info] Saved formula output instance to {0}").format(filename) ) except (IOError, EnvironmentError) as err: tkinter.messagebox.showwarning(_("arelle\u2122 - Error"), _("Failed to save {0}:\n{1}").format( self.filename, err), parent=self.parent) return True if self.filename is None: filename = tkinter.filedialog.asksaveasfilename( title=_("arelle\u2122 - Save File"), initialdir=".", filetypes=[(_("Xbrl file"), "*.x*")], defaultextension=".xbrl", parent=self.parent) if not filename: return False self.filename = filename if not self.filename.endswith(".xbrl"): self.filename += ".xbrl" try: with open(self.filename, "wb") as fh: pickle.dump(self.data, fh, pickle.HIGHEST_PROTOCOL) self.dirty = False self.uiShowStatus(_("Saved {0} items to {1}").format( len(self.data), self.filename), clearAfter=5000) self.parent.title(_("arelle\u2122 - {0}").format( os.path.basename(self.filename))) except (EnvironmentError, pickle.PickleError) as err: tkinter.messagebox.showwarning(_("arelle\u2122 - Error"), _("Failed to save {0}:\n{1}").format( self.filename, err), parent=self.parent) return True;
def generateHtmlEbaTablesetFiles(dts, indexFile, lang="en"): try: import os, io from arelle import Version, XbrlConst, XmlUtil from arelle.ViewFileRenderedGrid import viewRenderedGrid from arelle.ModelRenderingObject import ModelEuTable, ModelTable numTableFiles = 0 file = io.StringIO(''' <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Left"> <link type="text/css" rel="stylesheet" href="http://arelle.org/files/EBA/style20121210/eba.css" /> </head> <body class="LTR IE7 ENGB"> <ul class="CMSListMenuUL" id="Vertical2"/> </body> </html> ''' ) from arelle.ModelObjectFactory import parser parser, parserLookupName, parserLookupClass = parser(dts,None) from lxml import etree indexDocument = etree.parse(file,parser=parser,base_url=indexFile) file.close() #xmlDocument.getroot().init(self) ## is this needed ?? for listElt in indexDocument.iter(tag="{http://www.w3.org/1999/xhtml}ul"): break class nonTkBooleanVar(): def __init__(self, value=True): self.value = value def set(self, value): self.value = value def get(self): return self.value class View(): def __init__(self, tableOrELR, ignoreDimValidity, xAxisChildrenFirst, yAxisChildrenFirst): self.tblELR = tableOrELR # context menu boolean vars (non-tkinter boolean self.ignoreDimValidity = nonTkBooleanVar(value=ignoreDimValidity) self.xAxisChildrenFirst = nonTkBooleanVar(value=xAxisChildrenFirst) self.yAxisChildrenFirst = nonTkBooleanVar(value=yAxisChildrenFirst) indexBase = indexFile.rpartition(".")[0] groupTableRels = dts.modelXbrl.relationshipSet(XbrlConst.euGroupTable) modelTables = [] tblCssExtras=''' body {background-image:url('http://arelle.org/files/EBA/style20121210/lhsbackground.jpg')} table {background:#fff} ''' # order number is missing def viewTable(modelTable): if isinstance(modelTable, (ModelEuTable, ModelTable)): # status dts.modelManager.cntlr.addToLog("viewing: " + modelTable.id) # for table file name, use table ELR tblFile = os.path.join(os.path.dirname(indexFile), modelTable.id + ".html") viewRenderedGrid(dts, tblFile, lang=lang, sourceView=View(modelTable, False, False, True), cssExtras=tblCssExtras) # generaate menu entry elt = etree.SubElement(listElt, "{http://www.w3.org/1999/xhtml}li") elt.set("class", "CMSListMenuLI") elt.set("id", modelTable.id) elt = etree.SubElement(elt, "{http://www.w3.org/1999/xhtml}a") elt.text = modelTable.genLabel(lang=lang, strip=True) elt.set("class", "CMSListMenuLink") elt.set("href", "javascript:void(0)") elt.set("onClick", "javascript:parent.body.location.href='{0}';".format(modelTable.id + ".html")) elt.text = modelTable.genLabel(lang=lang, strip=True) else: # just a header # generaate menu entry elt = etree.SubElement(listElt, "{http://www.w3.org/1999/xhtml}li") elt.set("class", "CMSListMenuLink") elt.set("id", modelTable.id) elt.text = modelTable.label(lang=lang, strip=True) for rel in groupTableRels.fromModelObject(modelTable): viewTable(rel.toModelObject) for rootConcept in groupTableRels.rootConcepts: sourceline = 0 for rel in dts.modelXbrl.relationshipSet(XbrlConst.euGroupTable).fromModelObject(rootConcept): sourceline = rel.sourceline break modelTables.append((rootConcept, sourceline)) for modelTable, order in sorted(modelTables, key=lambda x: x[1]): viewTable(modelTable) with open(indexBase + "FormsFrame.html", "wt", encoding="utf-8") as fh: XmlUtil.writexml(fh, indexDocument, encoding="utf-8") with open(indexFile, "wt", encoding="utf-8") as fh: fh.write( ''' <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1"> <title>European Banking Authority - EBA - FINREP Taxonomy</title> <meta name="generator" content="Arelle(r) {0}" /> <meta name="provider" content="Aguilonius(r)" /> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <meta http-equiv="pragma" content="no-cache" /> <meta http-equiv="content-style-type" content="text/css" /> <meta http-equiv="content-script-type" content="text/javascript" /> <link type="text/css" rel="stylesheet" href="http://arelle.org/files/EBA/style20121210/eba.css" /> </head> <frameset border="0" frameborder="0" rows="90,*"> <frame name="head" src="{1}" scrolling="no" marginwidth="0" marginheight="10"/> <frameset bordercolor="#0000cc" border="10" frameborder="no" framespacing="0" cols="360, *"> <frame src="{2}" name="menu" bordercolor="#0000cc"/> <frame src="{3}" name="body" bordercolor="#0000cc"/> </frameset> </frameset> '''.format(Version.version, os.path.basename(indexBase) + "TopFrame.html", os.path.basename(indexBase) + "FormsFrame.html", os.path.basename(indexBase) + "CenterLanding.html", )) with open(indexBase + "TopFrame.html", "wt", encoding="utf-8") as fh: fh.write( ''' <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Top"> <link type="text/css" rel="stylesheet" href="http://arelle.org/files/EBA/style20121210/eba.css" /> </head> <body class="LTR IE7 ENGB"> <div id="topsection"> <div id="topsectionLeft" style="cursor:pointer;" onclick="location.href='http://www.eba.europa.eu/home.aspx';"></div> <div id="topsectionRight"></div> <div id="topnavigation"> <ul id="menuElem"> <li><a href="http://www.eba.europa.eu/topnav/Contacts.aspx">Contacts</a></li> <li><a href="http://www.eba.europa.eu/topnav/Links.aspx">Links</a></li> <li><a href="http://www.eba.europa.eu/topnav/Sitemap.aspx">Sitemap</a></li> <li><a href="http://www.eba.europa.eu/topnav/Legal-Notice.aspx">Legal Notice</a></li> </ul> </div> </body> </html> ''') with open(indexBase + "CenterLanding.html", "wt", encoding="utf-8") as fh: fh.write( ''' <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Center"> <link type="text/css" rel="stylesheet" href="http://http://arelle.org/files/EBA/style20121210/eba.css" /> </head> <body class="LTR IE7 ENGB"> <div id="plc_lt_zoneContent_usercontrol_userControlElem_ContentPanel"> <div id="plc_lt_zoneContent_usercontrol_userControlElem_PanelTitle"> <div id="pagetitle" style="float:left;width:500px;"> <h1>Taxonomy Tables Viewer</h1> </div> </div> </div> <div style="clear:both;"></div> <div id="contentcenter"> <p style="text-align: justify; margin-top: 0pt; margin-bottom: 0pt">Please select tables to view by clicking in the left column.</p> </div> </body> </html> ''') # to merge gif's and style sheets, use a zipfile sibling of the python plug-in file. #import zipfile #zf = zipfile.ZipFile(__file__.rpartition('.')[0] + "Files.zip", mode="r") #zf.extractall(path=os.path.dirname(indexBase)) #zf.close() dts.info("info:saveEBAtables", _("Tables index file of %(entryFile)s has %(numberTableFiles)s table files with index file %(indexFile)s."), modelObject=dts, entryFile=dts.uri, numberTableFiles=numTableFiles, indexFile=indexFile) dts.modelManager.showStatus(_("Saved EBA HTML Table Files"), 5000) except Exception as ex: dts.error("exception", _("HTML EBA Tableset files generation exception: %(error)s"), error=ex, modelXbrl=dts, exc_info=True)
def runFromExcel(self, options): testGenFileName = options.excelfilename #testGenFileName = r"C:\Users\Herm Fischer\Documents\mvsl\projects\XBRL.org\conformance-versioning\trunk\versioningReport\conf\creation\1000-2000-index.xls" testGenDir = os.path.dirname(testGenFileName) timeNow = XmlUtil.dateunionValue(datetime.datetime.now()) if options.testfiledate: today = options.testfiledate else: today = XmlUtil.dateunionValue(datetime.date.today()) startedAt = time.time() self.logMessages = [] logMessagesFile = testGenDir + os.sep + 'logGenerationMessages.txt' modelTestcases = ModelXbrl.create(self.modelManager) testcaseIndexBook = xlrd.open_workbook(testGenFileName) testcaseIndexSheet = testcaseIndexBook.sheet_by_index(0) self.addToLog(_("[info] xls loaded in {0:.2} secs at {1}").format(time.time() - startedAt, timeNow)) # start index file indexFiles = [testGenDir + os.sep + 'creationTestcasesIndex.xml', testGenDir + os.sep + 'consumptionTestcasesIndex.xml'] indexDocs = [xml.dom.minidom.parseString( '<?xml version="1.0" encoding="UTF-8"?>' '<!-- XBRL Versioning 1.0 {0} Tests -->' '<!-- Copyright 2011 XBRL International. All Rights Reserved. -->' '<?xml-stylesheet type="text/xsl" href="infrastructure/testcases-index.xsl"?>' '<testcases name="XBRL Versioning 1.0 Consumption Tests" date="{1}" ' ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' ' xsi:noNamespaceSchemaLocation="infrastructure/testcases-index.xsd">' '</testcases>'.format(purpose, today) ) for purpose in ("Creation","Consumption")] testcasesElements = [XmlUtil.child(indexDoc, None, "testcases") for indexDoc in indexDocs] priorTestcasesDir = None testcaseFiles = None testcaseDocs = None for iRow in range(1, testcaseIndexSheet.nrows): row = testcaseIndexSheet.row(iRow) if row[0].ctype == xlrd.XL_CELL_EMPTY or row[1].ctype == xlrd.XL_CELL_EMPTY or row[2].ctype == xlrd.XL_CELL_EMPTY: continue testDir = row[0].value uriFrom = row[1].value uriTo = row[2].value intention = row[3].value if intention is None or len(intention) == 0: continue # test not ready to run reason = row[4].value expectedEvent = row[5].value base = os.path.join(os.path.dirname(testGenFileName),testDir) + os.sep self.addToLog(_("[info] testcase uriFrom {0}").format(uriFrom)) if uriFrom and uriTo and reason.lower() not in ("n.a.", "error") and expectedEvent != "N.A.": for URIs, msg, isFrom in ((uriFrom, _("loading from DTS"), True), (uriTo, _("loading to DTS"), False)): if ',' not in URIs: modelDTS = ModelXbrl.load(self.modelManager, URIs, msg, base=base) else: modelDTS = ModelXbrl.create(self.modelManager, ModelDocument.Type.DTSENTRIES, self.webCache.normalizeUrl(URIs.replace(", ","_") + ".dts", base), isEntry=True) DTSdoc = modelDTS.modelDocument DTSdoc.inDTS = True for uri in URIs.split(','): doc = ModelDocument.load(modelDTS, uri.strip(), base=base) DTSdoc.referencesDocument[doc] = "import" #fake import doc.inDTS = True if isFrom: modelDTSfrom = modelDTS else: modelDTSto = modelDTS if modelDTSfrom and modelDTSto: # generate differences report reportUri = uriFrom.partition(',')[0] # first file reportDir = os.path.dirname(reportUri) if reportDir: reportDir += os.sep reportName = os.path.basename(reportUri).replace("from.xsd","report.xml") reportFile = reportDir + "report" + os.sep + reportName reportFullPath = self.webCache.normalizeUrl( reportFile, base) testcasesDir = os.path.dirname(os.path.dirname(reportFullPath)) if testcasesDir != priorTestcasesDir: # close prior report if priorTestcasesDir: for i,testcaseFile in enumerate(testcaseFiles): with open(testcaseFile, "w", encoding="utf-8") as fh: XmlUtil.writexml(fh, testcaseDocs[i], encoding="utf-8") testcaseName = os.path.basename(testcasesDir) testcaseFiles = [testcasesDir + os.sep + testcaseName + "-creation-testcase.xml", testcasesDir + os.sep + testcaseName + "-consumption-testcase.xml"] for i,testcaseFile in enumerate(testcaseFiles): XmlUtil.addChild(testcasesElements[i], None, "testcase", ("uri", testcaseFile[len(testGenDir)+1:].replace("\\","/")) ) # start testcase file testcaseDocs = [xml.dom.minidom.parseString( '<?xml version="1.0" encoding="UTF-8"?>' '<!-- Copyright 2011 XBRL International. All Rights Reserved. -->' '<?xml-stylesheet type="text/xsl" href="../../../infrastructure/test.xsl"?>' '<testcase name="XBRL Versioning 1.0 {1} Tests" date="{2}" ' ' xmlns="http://xbrl.org/2008/conformance"' ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' ' xsi:schemaLocation="http://xbrl.org/2008/conformance ../../../infrastructure/test.xsd">' '<creator>' '<name>Roland Hommes</name>' '<email>[email protected]</email>' '</creator>' '<name>{0}</name>' '<description>{0}</description>' '</testcase>'.format(testcaseName,purpose,today) ) for purpose in ("Creation","Consumption")] testcaseElements = [XmlUtil.child(testcaseDoc, conformanceNS, "testcase") for testcaseDoc in testcaseDocs] priorTestcasesDir = testcasesDir variationID = 1 try: os.makedirs(os.path.dirname(reportFullPath)) except WindowsError: pass # dir already exists modelVersReport = ModelVersReport.ModelVersReport(modelTestcases) modelVersReport.diffDTSes(reportFullPath,modelDTSfrom, modelDTSto) # check for expected elements if expectedEvent and expectedEvent not in ( "No change", "N.A."): if len(modelVersReport.xmlDocument.getElementsByTagNameNS('*',expectedEvent)) == 0: modelTestcases.error( "Generated test case {0} missing expected event {1}".format( reportName, expectedEvent), "wrn", "missingEvent") modelVersReport.close([]) for i,testcaseElt in enumerate(testcaseElements): variationElement = XmlUtil.addChild(testcaseElt, conformanceNS, "variation", attributes=("id", "_{0:02n}".format(variationID))) XmlUtil.addChild(variationElement, conformanceNS, "name", text=intention) dataElement = XmlUtil.addChild(variationElement, conformanceNS, "data") for schemaURIs, dtsAttr in ((uriFrom,"from"), (uriTo,"to")): for schemaURI in schemaURIs.split(","): XmlUtil.addChild(dataElement, conformanceNS, "schema", attributes=((("dts",dtsAttr),) + ((("readMeFirst","true"),) if i == 0 else ())), text=os.path.basename(schemaURI.strip())) resultElement = XmlUtil.addChild(variationElement, conformanceNS, "result") XmlUtil.addChild(resultElement if i == 0 else dataElement, conformanceNS, "versioningReport", attributes=(("readMeFirst","true") if i == 1 else ()), text="report/" + reportName) variationID += 1 with open(logMessagesFile, "w") as fh: fh.writelines(self.logMessages) if priorTestcasesDir: for i,testcaseFile in enumerate(testcaseFiles): with open(testcaseFile, "w", encoding="utf-8") as fh: XmlUtil.writexml(fh, testcaseDocs[i], encoding="utf-8") for i,indexFile in enumerate(indexFiles): with open(indexFile, "w", encoding="utf-8") as fh: XmlUtil.writexml(fh, indexDocs[i], encoding="utf-8")