Beispiel #1
0
def one_or_more(xc, p, contextItem, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    if len(args[0]) < 1:
        raise XPathContext.FunctionNumArgs(
            errCode='err:FORG0004',
            errText=_(
                'fn:one-or-more called with a sequence containing no items'))
    return args[0]
Beispiel #2
0
def exactly_one(xc, p, contextItem, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    if len(args[0]) != 1:
        raise XPathContext.FunctionNumArgs(
            errCode='err:FORG0005',
            errText=
            _('fn:exactly-one called with a sequence containing zero or more than one item'
              ))
    return args[0]
Beispiel #3
0
def zero_or_one(xc, p, contextItem, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    if len(args[0]) > 1:
        raise XPathContext.FunctionNumArgs(
            errCode='err:FORG0003',
            errText=
            _('fn:zero-or-one called with a sequence containing more than one item'
              ))
    return args[0]
Beispiel #4
0
def subsequence(xc, p, contextItem, args):
    if len(args) not in (2,3): raise XPathContext.FunctionNumArgs()
    l = len(args)
    if l < 2 or l > 3: raise XPathContext.FunctionNumArgs()
    sequence = args[0]
    start = _INT(round( numericArg(xc, p, args, 1) )) - 1
    if l == 3:
        length = _INT(round( numericArg(xc, p, args, 2) ))
        if start < 0:
            length += start
            if length < 0: length = 0
            start = 0 
        return sequence[start:start + length]
    if start < 0: start = 0
    return sequence[start:]
Beispiel #5
0
def linkbase_link_roles(xc, p, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    arcroleURI = stringArg(xc, args, 0, "xs:string")
    relationshipSet = xc.modelXbrl.relationshipSet(arcroleURI)
    if relationshipSet:
        return [anyURI(linkrole) for linkrole in relationshipSet.linkRoleUris]
    return ()
Beispiel #6
0
def my_fn_PDxEV(xc, p, contextItem, args):
    if len(args) != 2: raise XPathContext.FunctionNumArgs()
    PDseq = args[0] if isinstance(args[0], (list, tuple)) else (args[0], )
    EVseq = args[1] if isinstance(args[1], (list, tuple)) else (args[1], )
    dimQname = qname("{http://www.example.com/wgt-avg}ExposuresDimension")
    PDxEV = []
    for pd in PDseq:
        if pd.context is not None:
            pdDim = pd.context.dimValue(dimQname)
            for ev in EVseq:
                if ev.context is not None:
                    evDim = ev.context.dimValue(dimQname)
                    if pdDim is not None and isinstance(
                            pdDim, ModelDimensionValue):
                        dimEqual = pdDim.isEqualTo(evDim,
                                                   equalMode=XbrlUtil.S_EQUAL2)
                    elif evDim is not None and isinstance(
                            evDim, ModelDimensionValue):
                        dimEqual = evDim.isEqualTo(pdDim,
                                                   equalMode=XbrlUtil.S_EQUAL2)
                    else:
                        dimEqual = (pdDim == evDim)
                    if dimEqual:
                        PDxEV.append(pd.xValue * ev.xValue)
                        break
    return PDxEV
Beispiel #7
0
def fn_sum(xc, p, contextItem, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    addends = xc.atomize(p, args[0])
    try:
        if len(addends) == 0:
            return 0  # xpath allows empty sequence argument
        hasFloat = False
        hasDecimal = False
        for a in addends:
            if math.isnan(a):
                return NaN
            if isinstance(a, float):
                hasFloat = True
            elif isinstance(a, Decimal):
                hasDecimal = True
        if hasFloat and hasDecimal:  # promote decimals to float
            addends = [
                float(a) if isinstance(a, Decimal) else a for a in addends
            ]
        return sum(addends)
    except TypeError:
        raise XPathContext.FunctionArgType(1,
                                           "summable sequence",
                                           addends,
                                           errCode='err:FORG0001')
Beispiel #8
0
def concept_data_type(xc, p, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    typeQname = concept(xc, p, args).typeQname
    if not typeQname or typeQname.localName.endswith(
            ModelObject.anonymousTypeSuffix):
        return ()
    return typeQname
Beispiel #9
0
def seconds_from_duration(xc, p, contextItem, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    d = anytypeArg(xc, args, 0, 'duration', missingArgFallback=())
    if d == (): return d
    if isinstance(d, DayTimeDuration): return 0
    if isinstance(d, YearMonthDuration): return d.dayHrsMinsSecs[2]
    raise XPathContext.FunctionArgType(1,"xs:duration")    
Beispiel #10
0
def fn_dateTime(xc, p, contextItem, args):
    if len(args) != 2: raise XPathContext.FunctionNumArgs()
    date = anytypeArg(xc, args, 0, "xs:date", missingArgFallback=())
    time = anytypeArg(xc, args, 1, "xs:time", missingArgFallback=())
    if date is None or time is None:
        return ()
    return dateTime(date) + dayTimeDuration(time)
Beispiel #11
0
def  my_fn_PDxEV(xc, p, contextItem, args):
    if len(args) != 2: raise XPathContext.FunctionNumArgs()
    PDseq = flattenSequence(args[0])
    EVseq = flattenSequence(args[1])
    dimQname = qname("{http://www.example.com/wgt-avg}ExposuresDimension")
    PDxEV = []
    for pd in PDseq:
        if pd.context is not None:
            pdDim = pd.context.dimValue(dimQname)
            for ev in EVseq:
                if ev.context is not None:
                    evDim = ev.context.dimValue(dimQname)
                    if pdDim is not None and isinstance(pdDim,ModelDimensionValue):
                        dimEqual =  pdDim.isEqualTo(evDim, equalMode=XbrlUtil.S_EQUAL2)
                    elif evDim is not None and isinstance(evDim,ModelDimensionValue):
                        dimEqual =  evDim.isEqualTo(pdDim, equalMode=XbrlUtil.S_EQUAL2)
                    else:
                        dimEqual = (pdDim == evDim)
                    if dimEqual:
                        pdX = pd.xValue
                        evX = ev.xValue
                        # type promotion required
                        if isinstance(pdX,Decimal) and isinstance(evX,float):
                            pdX = float(pdX)
                        elif isinstance(evX,Decimal) and isinstance(pdX,float):
                            pdX = float(evX)
                        PDxEV.append(pdX * evX)
                        break
    return PDxEV
Beispiel #12
0
def doc(xc, p, contextItem, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    uri = stringArg(xc, args, 0, "xs:string", emptyFallback=None)
    if uri is None:
        return ()
    if xc.progHeader is None or xc.progHeader.element is None:
        raise XPathContext.XPathException(
            p, 'err:FODC0005',
            _('Function xf:doc no formula resource element for {0}').format(
                uri))
    if not UrlUtil.isValid(uri):
        raise XPathContext.XPathException(
            p, 'err:FODC0005',
            _('Function xf:doc $uri is not valid {0}').format(uri))
    normalizedUri = xc.modelXbrl.modelManager.cntlr.webCache.normalizeUrl(
        uri,
        xc.progHeader.element.modelDocument.baseForElement(
            xc.progHeader.element))
    if normalizedUri in xc.modelXbrl.urlDocs:
        return xc.modelXbrl.urlDocs[normalizedUri].xmlDocument
    modelDocument = ModelDocument.load(xc.modelXbrl, normalizedUri)
    if modelDocument is None:
        raise XPathContext.XPathException(
            p, 'err:FODC0005',
            _('Function xf:doc $uri not successfully loaded {0}').format(uri))
    # assure that document is validated
    XmlValidate.validate(xc.modelXbrl, modelDocument.xmlRootElement)
    return modelDocument.xmlDocument
Beispiel #13
0
def xfxc_element(xc, p, contextItem, args):
    if not 2 <= len(args) <= 4: raise XPathContext.FunctionNumArgs()
    qn = qnameArg(xc, p, args, 0, 'QName', emptyFallback=None)
    attrArg = args[1] if isinstance(args[1], (list, tuple)) else (args[1], )
    # attributes have to be pairs
    if attrArg:
        if len(attrArg) & 1 or any(
                not isinstance(attrArg[i], (QName, _STR_BASE))
                for i in range(0, len(attrArg), 2)):
            raise XPathContext.FunctionArgType(
                1,
                "((xs:qname|xs:string),xs:anyAtomicValue)",
                errCode="xfxce:AttributesNotNameValuePairs")
        else:
            attrParam = [
                (attrArg[i], attrArg[i + 1]
                 )  # need name-value pairs for XmlUtil function
                for i in range(0, len(attrArg), 2)
            ]
    else:
        attrParam = None

    value = atomicArg(xc, p, args, 2, "xs:anyAtomicType", emptyFallback='')
    if not value:  # be sure '' is None so no text node is created
        value = None
    if len(args) < 4:
        childElements = None
    else:
        childElements = xc.flattenSequence(args[3])

    # scratchpad instance document emulates fn:doc( ) to hold XML nodes
    scratchpadXmlDocUrl = "http://www.xbrl.org/2012/function/creation/xml_scratchpad.xml"
    if scratchpadXmlDocUrl in xc.modelXbrl.urlDocs:
        modelDocument = xc.modelXbrl.urlDocs[scratchpadXmlDocUrl]
    else:
        # create scratchpad xml document
        # this will get the fake instance document in the list of modelXbrl docs so that it is garbage collected
        from arelle import ModelDocument
        modelDocument = ModelDocument.create(
            xc.modelXbrl,
            ModelDocument.Type.UnknownXML,
            scratchpadXmlDocUrl,
            initialXml=
            "<xfc:dummy xmlns:xfc='http://www.xbrl.org/2012/function/creation'/>"
        )

    newElement = XmlUtil.addChild(modelDocument.xmlRootElement,
                                  qn,
                                  attributes=attrParam,
                                  text=value)
    if childElements:
        for element in childElements:
            if isinstance(element, etree.ElementBase):
                newElement.append(element)

    # node myst be validated for use in instance creation (typed dimension references)
    XmlValidate.validate(xc.modelXbrl, newElement)

    return newElement
Beispiel #14
0
def element_name(xc, p, args, elementParent=False):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    modelRel = anytypeArg(xc, args, 0, "arelle:ModelRelationship", None)
    if not modelRel:
        raise XPathContext.FunctionArgType(1, "arelle:modelRelationship")
    element = modelRel.element
    if elementParent: element = element.parentNode
    return qname(element)
Beispiel #15
0
def measure_name(xc, p, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    if len(args[0]) != 1: raise XPathContext.FunctionArgType(1, "xbrl:measure")
    unit = args[0][0]
    if isinstance(unit,xml.dom.Node) and unit.nodeType == 1 and \
       unit.localName == "measure" and unit.namespaceURI == XbrlConst.xbrli:
        return qname(unit, XmlUtil.text(unit))
    raise XPathContext.FunctionArgType(1, "xbrl:unit")
Beispiel #16
0
def fn_round(xc, p, contextItem, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    x = numericArg(xc, p, args)
    if math.isinf(x) or math.isnan(x):
        return x
    return _INT(
        x +
        (DECIMAL_5 if isinstance(x, Decimal) else .5))  # round towards +inf
Beispiel #17
0
def call(xc, p, localname, args):
    try:
        if localname not in ixtFunctions: raise ixtFunctionNotAvailable
        if len(args) != 1: raise XPathContext.FunctionNumArgs()
        if len(args[0]) != 1: raise XPathContext.FunctionArgType(1,"xs:string")
        return ixtFunctions[localname](str(args[0][0]))
    except ixtFunctionNotAvailable:
        raise XPathContext.FunctionNotAvailable("xfi:{0}".format(localname))
Beispiel #18
0
def xfm_tan(xc, p, contextItem, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    x = numericArg(xc, p, args, 0, emptyFallback=())
    if x != ():
        if math.isinf(x):
            return NaN
        return math.tan(x)
    return ()
Beispiel #19
0
def is_period_type(args, periodElement):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    if len(args[0]) != 1: raise XPathContext.FunctionArgType(1, "xbrl:period")
    period = args[0][0]
    if isinstance(period,xml.dom.Node) and period.nodeType == 1 and \
       period.localName == "period" and period.namespaceURI == XbrlConst.xbrli:
        return XmlUtil.hasChild(period, XbrlConst.xbrli, periodElement)
    raise XPathContext.FunctionArgType(1, "xbrl:period")
Beispiel #20
0
def call(xc, p, qn, args):
    try:
        _ixtFunction = ixtNamespaceFunctions[qn.namespaceURI][qn.localName]
    except KeyError:
        raise XPathContext.FunctionNotAvailable(str(qn))
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    if len(args[0]) != 1: raise XPathContext.FunctionArgType(1, "xs:string")
    return _ixtFunction(str(args[0][0]))
Beispiel #21
0
def  format_number(xc, p, args):
    if len(args) != 2: raise XPathContext.FunctionNumArgs()
    value = numericArg(xc, p, args, 0, missingArgFallback='NaN', emptyFallback='NaN')
    picture = stringArg(xc, args, 1, "xs:string", missingArgFallback='', emptyFallback='')
    try:
        return format_picture(xc.modelXbrl.locale, value, picture)
    except ValueError as err:
        raise XPathContext.XPathException(p, 'err:FODF1310', str(err) )
Beispiel #22
0
def arcrole_definition(xc, p, args):
    if len(args) == 2: raise XPathContext.FunctionNumArgs()
    arcroleURI = stringArg(xc, args, 0, "xs:string", emptyFallback='')
    modelArcroleTypes = xc.modelXbrl.arcroleTypes.get(arcroleURI)
    if modelArcroleTypes is not None and len(modelArcroleTypes) > 0:
        arcroledefinition = modelArcroleTypes[0].definition
        if arcroledefinition is not None: return arcroledefinition
    return ()
Beispiel #23
0
def fn_abs(xc, p, contextItem, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    x = numericArg(xc, p, args)
    if math.isinf(x): 
        x = float('inf')
    elif not math.isnan(x): 
        x = abs(x)
    return x
Beispiel #24
0
def matches(xc, p, contextItem, args):
    if not 2 <= len(args) <= 3: raise XPathContext.FunctionNumArgs()
    input = stringArg(xc, args, 0, "xs:string?", emptyFallback=())
    pattern = stringArg(xc, args, 1, "xs:string", emptyFallback=())
    try:
        return bool(re.search(pattern,input,flags=regexFlags(xc, p, args, 2)))
    except sre_constants.error as err:
        raise XPathContext.XPathException(p, 'err:FORX0002', _('fn:matches regular expression pattern error: {0}').format(err))
Beispiel #25
0
def concat(xc, p, contextItem, args):
    if len(args) < 2: raise XPathContext.FunctionNumArgs()
    atomizedArgs = []
    for i in range(len(args)):
        item = anytypeArg(xc, args, i, "xs:anyAtomicType?")
        if item != ():
            atomizedArgs.append( FunctionXs.xsString( xc, p, xc.atomize(p, item) ) )
    return ''.join(atomizedArgs)
Beispiel #26
0
def string(xc, p, contextItem, args):
    if len(args) > 1: raise XPathContext.FunctionNumArgs()
    x = stringArg(xc,
                  args,
                  0,
                  "item()?",
                  missingArgFallback=contextItem,
                  emptyFallback='')
    return str(x)
Beispiel #27
0
def fn_round_half_to_even(xc, p, contextItem, args):
    if len(args) > 2 or len(args) == 0: raise XPathContext.FunctionNumArgs()
    x = numericArg(xc, p, args)
    if len(args) == 2:
        precision = args[1]
        if len(precision) != 1 or not isinstance(precision[0],_INT_TYPES): raise XPathContext.FunctionArgType(2,"integer")
        precision = precision[0]
        return round(x, precision)
    return round(x)
Beispiel #28
0
def xfm_atan(xc, p, contextItem, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    x = numericArg(xc, p, args, 0, emptyFallback=())
    if x != ():
        try:
            return math.atan(x)
        except ValueError:
            return NaN
    return ()
Beispiel #29
0
def replace(xc, p, contextItem, args):
    if not 3 <= len(args) <= 4: raise XPathContext.FunctionNumArgs()
    input = stringArg(xc, args, 0, "xs:string?", emptyFallback=())
    pattern = stringArg(xc, args, 1, "xs:string", emptyFallback=())
    replacement = stringArg(xc, args, 2, "xs:string", emptyFallback=())
    return re.sub(pattern,
                  replacement,
                  input,
                  flags=regexFlags(xc, p, args, 3))
Beispiel #30
0
def compare(xc, p, contextItem, args):
    if len(args) == 3: raise fnFunctionNotAvailable()
    if len(args) != 2: raise XPathContext.FunctionNumArgs()
    comparand1 = stringArg(xc, args, 0, "xs:string?", emptyFallback=())
    comparand2 = stringArg(xc, args, 1, "xs:string?", emptyFallback=())
    if comparand1 == () or comparand2 == (): return ()
    if comparand1 == comparand2: return 0
    if comparand1 < comparand2: return -1
    return 1