Exemple #1
0
 def getTrNames(self, trReg):
     trNS = self.trPrefixNSs[trReg]
     trPrefix = trReg.split()[0] # for ixt remove TRn part
     setXmlns(self.modelXbrl.modelDocument, trPrefix, trNS)
     if trNS in ixtNamespaceFunctions:
         return sorted("{}:{}".format(trPrefix, key)
                       for key in ixtNamespaceFunctions[trNS].keys())
     # custom transforms
     return sorted(str(trQn)
                   for trQn in self.modelXbrl.modelManager.customTransforms.keys()
                   if trQn.prefix == trPrefix)
Exemple #2
0
 def transform(self, trReg, trName, sourceValue):
     try:                            
         trNS = self.trPrefixNSs[trReg]
         trPrefix = trReg.split()[0] # for ixt remove TRn part
         setXmlns(self.modelXbrl.modelDocument, trPrefix, trNS)
         self.modelXbrl.modelManager.showStatus(_("Executing call"))
         elt = self.modelXbrl.modelDocument.xmlRootElement
         if ':' in trName:
             prefixedFnName = trName
         else:
             prefixedFnName = "{}:{}".format(trPrefix, trName)
         callExprStack = XPathParser.parse(self.validator, 
                                           '{}("{}")'.format(prefixedFnName, sourceValue),
                                           elt, trName + " call", Trace.CALL)
         xpathContext = XPathContext.create(self.modelXbrl, sourceElement=elt)
         result = xpathContext.evaluate(callExprStack)
         while result and isinstance(result, (tuple,list,set)):
             result = next(iter(result)) # de-sequence result
         return result
     except XPathContext.XPathException as err:
         self.modelXbrl.error(err.code, err.message)
         return err
Exemple #3
0
def createTargetInstance(modelXbrl,
                         targetUrl,
                         targetDocumentSchemaRefs,
                         filingFiles,
                         baseXmlLang=None,
                         defaultXmlLang=None):
    def addLocallyReferencedFile(elt, filingFiles):
        if elt.tag in ("a", "img"):
            for attrTag, attrValue in elt.items():
                if attrTag in ("href", "src") and not isHttpUrl(
                        attrValue) and not os.path.isabs(attrValue):
                    attrValue = attrValue.partition('#')[0]  # remove anchor
                    if attrValue:  # ignore anchor references to base document
                        attrValue = os.path.normpath(
                            attrValue
                        )  # change url path separators to host separators
                        file = os.path.join(sourceDir, attrValue)
                        if modelXbrl.fileSource.isInArchive(
                                file,
                                checkExistence=True) or os.path.exists(file):
                            filingFiles.add(file)

    targetInstance = ModelXbrl.create(
        modelXbrl.modelManager,
        newDocumentType=Type.INSTANCE,
        url=targetUrl,
        schemaRefs=targetDocumentSchemaRefs,
        isEntry=True,
        discover=False)  # don't attempt to load DTS
    ixTargetRootElt = modelXbrl.ixTargetRootElements[getattr(
        modelXbrl, "ixdsTarget", None)]
    langIsSet = False
    # copy ix resources target root attributes
    for attrName, attrValue in ixTargetRootElt.items():
        if attrName != "target":  # ix:references target is not mapped to xbrli:xbrl
            targetInstance.modelDocument.xmlRootElement.set(
                attrName, attrValue)
        if attrName == "{http://www.w3.org/XML/1998/namespace}lang":
            langIsSet = True
            defaultXmlLang = attrValue
        if attrName.startswith("{"):
            ns, _sep, ln = attrName[1:].rpartition("}")
            if ns:
                prefix = xmlnsprefix(ixTargetRootElt, ns)
                if prefix not in (None, "xml"):
                    setXmlns(targetInstance.modelDocument, prefix, ns)

    if not langIsSet and baseXmlLang:
        targetInstance.modelDocument.xmlRootElement.set(
            "{http://www.w3.org/XML/1998/namespace}lang", baseXmlLang)
        if defaultXmlLang is None:
            defaultXmlLang = baseXmlLang  # allows facts/footnotes to override baseXmlLang
    ValidateXbrlDimensions.loadDimensionDefaults(
        targetInstance)  # need dimension defaults
    # roleRef and arcroleRef (of each inline document)
    for sourceRefs in (modelXbrl.targetRoleRefs, modelXbrl.targetArcroleRefs):
        for roleRefElt in sourceRefs.values():
            addChild(targetInstance.modelDocument.xmlRootElement,
                     roleRefElt.qname,
                     attributes=roleRefElt.items())

    # contexts
    for context in sorted(modelXbrl.contexts.values(),
                          key=lambda c: c.objectIndex
                          ):  # contexts may come from multiple IXDS files
        ignore = targetInstance.createContext(
            context.entityIdentifier[0],
            context.entityIdentifier[1],
            'instant' if context.isInstantPeriod else
            'duration' if context.isStartEndPeriod else 'forever',
            context.startDatetime,
            context.endDatetime,
            None,
            context.qnameDims, [], [],
            id=context.id)
    for unit in sorted(modelXbrl.units.values(), key=lambda u: u.objectIndex
                       ):  # units may come from multiple IXDS files
        measures = unit.measures
        ignore = targetInstance.createUnit(measures[0],
                                           measures[1],
                                           id=unit.id)

    modelXbrl.modelManager.showStatus(_("Creating and validating facts"))
    newFactForOldObjId = {}

    def createFacts(facts, parent):
        for fact in facts:
            if fact.isItem:  # HF does not de-duplicate, which is currently-desired behavior
                attrs = {"contextRef": fact.contextID}
                if fact.id:
                    attrs["id"] = fact.id
                if fact.isNumeric:
                    attrs["unitRef"] = fact.unitID
                    if fact.get("decimals"):
                        attrs["decimals"] = fact.get("decimals")
                    if fact.get("precision"):
                        attrs["precision"] = fact.get("precision")
                if fact.isNil:
                    attrs[XbrlConst.qnXsiNil] = "true"
                    text = None
                else:
                    text = fact.xValue if fact.xValid else fact.textValue
                for attrName, attrValue in fact.items():
                    if attrName.startswith("{"):
                        attrs[qname(
                            attrName, fact.nsmap
                        )] = attrValue  # using qname allows setting prefix in extracted instance
                newFact = targetInstance.createFact(fact.qname,
                                                    attributes=attrs,
                                                    text=text,
                                                    parent=parent)
                # if fact.isFraction, create numerator and denominator
                newFactForOldObjId[fact.objectIndex] = newFact
                if filingFiles is not None and fact.concept is not None and fact.concept.isTextBlock:
                    # check for img and other filing references so that referenced files are included in the zip.
                    for xmltext in [text] + CDATApattern.findall(text):
                        try:
                            for elt in XML("<body>\n{0}\n</body>\n".format(
                                    xmltext)).iter():
                                addLocallyReferencedFile(elt, filingFiles)
                        except (XMLSyntaxError, UnicodeDecodeError):
                            pass  # TODO: Why ignore UnicodeDecodeError?
            elif fact.isTuple:
                attrs = {}
                if fact.id:
                    attrs["id"] = fact.id
                if fact.isNil:
                    attrs[XbrlConst.qnXsiNil] = "true"
                for attrName, attrValue in fact.items():
                    if attrName.startswith("{"):
                        attrs[qname(attrName, fact.nsmap)] = attrValue
                newTuple = targetInstance.createFact(fact.qname,
                                                     attributes=attrs,
                                                     parent=parent)
                newFactForOldObjId[fact.objectIndex] = newTuple
                createFacts(fact.modelTupleFacts, newTuple)

    createFacts(modelXbrl.facts, None)
    modelXbrl.modelManager.showStatus(
        _("Creating and validating footnotes and relationships"))
    HREF = "{http://www.w3.org/1999/xlink}href"
    footnoteLinks = defaultdict(list)
    footnoteIdCount = {}
    for linkKey, linkPrototypes in modelXbrl.baseSets.items():
        arcrole, linkrole, linkqname, arcqname = linkKey
        if (linkrole and linkqname and arcqname and  # fully specified roles
                arcrole != "XBRL-footnotes" and any(
                    lP.modelDocument.type == Type.INLINEXBRL
                    for lP in linkPrototypes)):
            for linkPrototype in linkPrototypes:
                if linkPrototype not in footnoteLinks[linkrole]:
                    footnoteLinks[linkrole].append(linkPrototype)
    for linkrole in sorted(footnoteLinks.keys()):
        for linkPrototype in footnoteLinks[linkrole]:
            newLink = addChild(targetInstance.modelDocument.xmlRootElement,
                               linkPrototype.qname,
                               attributes=linkPrototype.attributes)
            for linkChild in linkPrototype:
                attributes = linkChild.attributes
                if isinstance(linkChild, LocPrototype):
                    if HREF not in linkChild.attributes:
                        linkChild.attributes[HREF] = \
                        "#" + elementFragmentIdentifier(newFactForOldObjId[linkChild.dereference().objectIndex])
                    addChild(newLink, linkChild.qname, attributes=attributes)
                elif isinstance(linkChild, ArcPrototype):
                    addChild(newLink, linkChild.qname, attributes=attributes)
                elif isinstance(linkChild, ModelInlineFootnote):
                    idUseCount = footnoteIdCount.get(linkChild.footnoteID,
                                                     0) + 1
                    if idUseCount > 1:  # if footnote with id in other links bump the id number
                        attributes = linkChild.attributes.copy()
                        attributes["id"] = "{}_{}".format(
                            attributes["id"], idUseCount)
                    footnoteIdCount[linkChild.footnoteID] = idUseCount
                    newChild = addChild(newLink,
                                        linkChild.qname,
                                        attributes=attributes)
                    xmlLang = linkChild.xmlLang
                    if xmlLang is not None and xmlLang != defaultXmlLang:  # default
                        newChild.set(
                            "{http://www.w3.org/XML/1998/namespace}lang",
                            xmlLang)
                    copyIxFootnoteHtml(
                        linkChild,
                        newChild,
                        targetModelDocument=targetInstance.modelDocument,
                        withText=True)

                    if filingFiles and linkChild.textValue:
                        footnoteHtml = XML("<body/>")
                        copyIxFootnoteHtml(linkChild, footnoteHtml)
                        for elt in footnoteHtml.iter():
                            addLocallyReferencedFile(elt, filingFiles)
    return targetInstance