def replace(xc, p, contextItem, args): if not 3 <= len(args) <= 4: raise XPathContext.FunctionNumArgs() input = stringArg(xc, args, 0, u"xs:string?", emptyFallback=u"") # empty string is default pattern = stringArg(xc, args, 1, u"xs:string", emptyFallback=u"") fnReplacement = stringArg(xc, args, 2, u"xs:string", emptyFallback=u"") if re.findall(ur"(^|[^\\])[$]|[$][^0-9]", fnReplacement): raise XPathContext.XPathException(p, u'err:FORX0004', _(u'fn:replace pattern \'$\' error in: {0}').format(fnReplacement))
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))
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))
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
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=()) fnReplacement = stringArg(xc, args, 2, "xs:string", emptyFallback=()) if re.findall(r"(^|[^\\])[$]|[$][^0-9]", fnReplacement): raise XPathContext.XPathException(p, 'err:FORX0004', _('fn:replace pattern \'$\' error in: {0}').format(fnReplacement)) reReplacement = re.sub(r"[\\][$]", "$", re.sub(r"(^|[^\\])[$]([1-9])", r"\\\2", fnReplacement)) try: return re.sub(pattern,reReplacement,input,flags=regexFlags(xc, p, args, 3)) except sre_constants.error as err: raise XPathContext.XPathException(p, 'err:FORX0002', _('fn:replace regular expression pattern error: {0}').format(err))
def fact_footnotes(xc, p, args): if len(args) != 5: raise XPathContext.FunctionNumArgs() itemObj = item(xc, args) linkroleURI = stringArg(xc, args, 1, "xs:string", emptyFallback='') if not linkroleURI: linkroleURI = XbrlConst.defaultLinkRole arcroleURI = stringArg(xc, args, 2, "xs:string", emptyFallback='') if not arcroleURI: arcroleURI = XbrlConst.factFootnote footnoteroleURI = stringArg(xc, args, 3, "xs:string", emptyFallback='') if not footnoteroleURI: footnoteroleURI = XbrlConst.footnote lang = stringArg(xc, args, 4, "xs:string", emptyFallback='') relationshipSet = xc.modelXbrl.relationshipSet(arcroleURI,linkroleURI) if relationshipSet: return relationshipSet.label(itemObj, footnoteroleURI, lang, returnMultiple=True) return ()
def translate(xc, p, contextItem, args): if len(args) != 3: raise XPathContext.FunctionNumArgs() arg = stringArg(xc, args, 0, "xs:string?", emptyFallback=()) mapString = stringArg(xc, args, 1, "xs:string", emptyFallback=()) transString = stringArg(xc, args, 2, "xs:string", emptyFallback=()) if arg == (): return () out = [] for c in arg: if c in mapString: i = mapString.index(c) if i < len(transString): out.append(transString[i]) else: out.append(c) return ''.join(out)
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 ()
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
def role_definition(xc, p, args): roleURI = stringArg(xc, args, 0, "xs:string", emptyFallback='') modelRoleTypes = xc.modelXbrl.roleTypes.get(roleURI) if modelRoleTypes is not None and len(modelRoleTypes) > 0: roledefinition = modelRoleTypes[0].definition if roledefinition is not None: return roledefinition return ()
def uncovered_aspect(xc, p, args): from arelle.ModelFormulaObject import aspectFromToken, Aspect from arelle.FormulaEvaluator import uncoveredAspectValue if len(args) not in (1,2): raise XPathContext.FunctionNumArgs() aspect = aspectFromToken.get(stringArg(xc, args, 0, "xs:token").strip()) if aspect == Aspect.DIMENSIONS: qn = qnameArg(xc, p, args, 1, 'QName', emptyFallback=None) # check function use after checking argument types if xc.progHeader is not None and xc.progHeader.element is not None: if xc.progHeader.element.localName not in ("formula", "consistencyAssertion", "valueAssertion", "message"): raise XPathContext.XPathException(p, 'xffe:invalidFunctionUse', _('Function xff:uncovered-aspect cannot be used on an XPath expression associated with a {0}').format(xc.progHeader.element.localName)) if xc.variableSet is not None and xc.variableSet.implicitFiltering == "false": raise XPathContext.XPathException(p, 'xffe:invalidFunctionUse', _('Function xff:uncovered-aspect cannot be used with implicitFiltering=false')) if aspect == Aspect.DIMENSIONS: if qn: modelConcept = xc.modelXbrl.qnameConcepts.get(qn) if modelConcept is not None and modelConcept.isDimensionItem: aspect = qn else: return () # not a dimension dimValue = uncoveredAspectValue(xc, aspect) if isinstance(dimValue, ModelDimensionValue): if dimValue.isExplicit: return dimValue.memberQname elif dimValue.isTyped: return dimValue # return the typedMember element, not its contents elif isinstance(dimValue, QName): # qname for explicit or node for typed return dimValue return () aspectValue = uncoveredAspectValue(xc, aspect) if aspectValue is None: return () return aspectValue
def fact_footnotes(xc, p, args): if len(args) != 5: raise XPathContext.FunctionNumArgs() itemObj = item(xc, args) linkroleURI = stringArg(xc, args, 1, "xs:string", emptyFallback='') if not linkroleURI: linkroleURI = XbrlConst.defaultLinkRole arcroleURI = stringArg(xc, args, 2, "xs:string", emptyFallback='') if not arcroleURI: arcroleURI = XbrlConst.factFootnote footnoteroleURI = stringArg(xc, args, 3, "xs:string", emptyFallback='') if not footnoteroleURI: footnoteroleURI = XbrlConst.footnote lang = stringArg(xc, args, 4, "xs:string", emptyFallback='') relationshipSet = xc.modelXbrl.relationshipSet(arcroleURI, linkroleURI) if relationshipSet: return relationshipSet.label(itemObj, footnoteroleURI, lang, returnMultiple=True) return ()
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 ()
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) )
def concept_label(xc, p, args): if len(args) == 5: raise xfiFunctionNotAvailable() if len(args) != 4: raise XPathContext.FunctionNumArgs() qnSource = qnameArg(xc, p, args, 0, 'QName', emptyFallback=None) srcConcept = xc.modelXbrl.qnameConcepts.get(qnSource) if srcConcept is None: return "" linkroleURI = stringArg(xc, args, 1, "xs:string", emptyFallback='') if not linkroleURI: linkroleURI = XbrlConst.defaultLinkRole labelroleURI = stringArg(xc, args, 2, "xs:string", emptyFallback='') if not labelroleURI: labelroleURI = XbrlConst.standardLabel lang = stringArg(xc, args, 3, "xs:string", emptyFallback='') relationshipSet = xc.modelXbrl.relationshipSet(XbrlConst.conceptLabel,linkroleURI) if relationshipSet is not None: label = relationshipSet.label(srcConcept, labelroleURI, lang) if label is not None: return label return ""
def concept_label(xc, p, args): if len(args) == 5: raise xfiFunctionNotAvailable() if len(args) != 4: raise XPathContext.FunctionNumArgs() qnSource = qnameArg(xc, p, args, 0, 'QName', emptyFallback=None) srcConcept = xc.modelXbrl.qnameConcepts.get(qnSource) if not srcConcept: return "" linkroleURI = stringArg(xc, args, 1, "xs:string", emptyFallback='') if not linkroleURI: linkroleURI = XbrlConst.defaultLinkRole labelroleURI = stringArg(xc, args, 2, "xs:string", emptyFallback='') if not labelroleURI: labelroleURI = XbrlConst.standardLabel lang = stringArg(xc, args, 3, "xs:string", emptyFallback='') relationshipSet = xc.modelXbrl.relationshipSet(XbrlConst.conceptLabel, linkroleURI) if relationshipSet: label = relationshipSet.label(srcConcept, labelroleURI, lang) if label is not None: return label return ""
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)
def filter_member_network_selection(xc, p, args): if len(args) != 5: raise XPathContext.FunctionNumArgs() qnDim = qnameArg(xc, p, args, 0, 'QName', emptyFallback=None) qnMem = qnameArg(xc, p, args, 1, 'QName', emptyFallback=None) linkroleURI = stringArg(xc, args, 2, "xs:string") arcroleURI = stringArg(xc, args, 3, "xs:string") axis = stringArg(xc, args, 4, "xs:string") if not axis in ('descendant-or-self', 'child-or-self', 'descendant', 'child'): return () dimConcept = xc.modelXbrl.qnameConcepts.get(qnDim) if not dimConcept or not dimConcept.isDimensionItem: raise XPathContext.XPathException( p, 'xfie:invalidDimensionQName', _('Argument 1 {0} is not a dimension concept QName.').format( qnDim)) memConcept = xc.modelXbrl.qnameConcepts.get(qnMem) if not memConcept or not memConcept.isDomainMember: # removed error 2011-03-10: raise XPathContext.XPathException(p, 'xfie:unrecognisedExplicitDimensionValueQName', _('Argument 1 {0} is not a member concept QName.').format(qnMem)) return () relationshipSet = xc.modelXbrl.relationshipSet(arcroleURI, linkroleURI) if relationshipSet: members = set() linkQnames = set() arcQnames = set() if axis.endswith("-or-self"): members.add(qnMem) fromRels = relationshipSet.fromModelObject(memConcept) if fromRels: filter_member_network_members(relationshipSet, fromRels, axis.startswith("descendant"), members, linkQnames, arcQnames) ''' removed 2011-03-10: if len(linkQnames) > 1 or len(arcQnames) > 1: raise XPathContext.XPathException(p, 'xfie:ambiguousFilterMemberNetwork', _('Network of linkrole {0} and arcrole {1} dimension {2} from {3} is ambiguous because of multiple link elements, {4}, or arc elements {5}').format( linkroleURI, arcroleURI, qnDim, qnMem, linkQnames, arcQnames)) ''' return members # no fromRels, must be a toRel or else the qname is not in the member network if relationshipSet.toModelObject(memConcept): return members # valid situation, the member exists as a leaf node # removed error 2011-03-10: raise XPathContext.XPathException(p, 'xfie:unrecognisedExplicitDimensionValueQName', _('Argument 1 {0} member is not in the network.').format(qnMem)) return ()
def string_join(xc, p, contextItem, args): if len(args) != 2: raise XPathContext.FunctionNumArgs() joiner = stringArg(xc, args, 1, "xs:string") atomizedArgs = [] for x in xc.atomize( p, args[0] ): if isinstance(x, _STR_BASE): atomizedArgs.append(x) else: raise XPathContext.FunctionArgType(0,"xs:string*") return joiner.join(atomizedArgs)
def substring_functions(xc, args, contains=None, startEnd=None, beforeAfter=None): if len(args) == 3: raise fnFunctionNotAvailable() if len(args) != 2: raise XPathContext.FunctionNumArgs() string = stringArg(xc, args, 0, "xs:string?") portion = stringArg(xc, args, 1, "xs:string") if contains == True: return portion in string elif startEnd == True: return string.startswith(portion) elif startEnd == False: return string.endswith(portion) elif beforeAfter is not None: if portion == '': return '' try: if beforeAfter: return string.partition( portion )[0] else: return string.rpartition( portion )[2] except ValueError: return '' raise fnFunctionNotAvailable() # wrong arguments?
def regexFlags(xc, p, args, n): f = 0 flagsArg = stringArg(xc, args, n, "xs:string", missingArgFallback="", emptyFallback="") for c in flagsArg: if c == 's': f |= re.S elif c == 'm': f |= re.M elif c == 'i': f |= re.I elif c == 'x': f |= re.X else: raise XPathContext.XPathException(p, 'err:FORX0001', _('Regular expression interpretation flag unrecognized: {0}').format(flagsArg)) return f
def filter_member_network_selection(xc, p, args): if len(args) != 5: raise XPathContext.FunctionNumArgs() qnDim = qnameArg(xc, p, args, 0, 'QName', emptyFallback=None) qnMem = qnameArg(xc, p, args, 1, 'QName', emptyFallback=None) linkroleURI = stringArg(xc, args, 2, "xs:string") arcroleURI = stringArg(xc, args, 3, "xs:string") axis = stringArg(xc, args, 4, "xs:string") if not axis in ('descendant-or-self', 'child-or-self', 'descendant', 'child'): return () dimConcept = xc.modelXbrl.qnameConcepts.get(qnDim) if dimConcept is None or not dimConcept.isDimensionItem: raise XPathContext.XPathException(p, 'xfie:invalidDimensionQName', _('Argument 1 {0} is not a dimension concept QName.').format(qnDim)) memConcept = xc.modelXbrl.qnameConcepts.get(qnMem) if memConcept is None or not memConcept.isDomainMember: # removed error 2011-03-10: raise XPathContext.XPathException(p, 'xfie:unrecognisedExplicitDimensionValueQName', _('Argument 1 {0} is not a member concept QName.').format(qnMem)) return () relationshipSet = xc.modelXbrl.relationshipSet(arcroleURI, linkroleURI) if relationshipSet is not None: members = set() linkQnames = set() arcQnames = set() if axis.endswith("-or-self"): members.add(qnMem) fromRels = relationshipSet.fromModelObject(memConcept) if fromRels is not None: filter_member_network_members(relationshipSet, fromRels, axis.startswith("descendant"), members, linkQnames, arcQnames) ''' removed 2011-03-10: if len(linkQnames) > 1 or len(arcQnames) > 1: raise XPathContext.XPathException(p, 'xfie:ambiguousFilterMemberNetwork', _('Network of linkrole {0} and arcrole {1} dimension {2} from {3} is ambiguous because of multiple link elements, {4}, or arc elements {5}').format( linkroleURI, arcroleURI, qnDim, qnMem, linkQnames, arcQnames)) ''' return members # no fromRels, must be a toRel or else the qname is not in the member network if relationshipSet.toModelObject(memConcept): return members # valid situation, the member exists as a leaf node # removed error 2011-03-10: raise XPathContext.XPathException(p, 'xfie:unrecognisedExplicitDimensionValueQName', _('Argument 1 {0} member is not in the network.').format(qnMem)) return ()
def substring(xc, p, contextItem, args): l = len(args) if l < 2 or l > 3: raise XPathContext.FunctionNumArgs() string = stringArg(xc, args, 0, "xs:string?") 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 string[start:start + length] if start < 0: start = 0 return string[start:]
def uncovered_aspect(xc, p, args): from arelle.ModelFormulaObject import aspectFromToken, Aspect from arelle.FormulaEvaluator import uncoveredAspectValue if len(args) not in (1, 2): raise XPathContext.FunctionNumArgs() aspect = aspectFromToken.get(stringArg(xc, args, 0, "xs:token").strip()) if aspect == Aspect.DIMENSIONS: qn = qnameArg(xc, p, args, 1, 'QName', emptyFallback=None) # check function use after checking argument types if xc.progHeader and xc.progHeader.element: if xc.progHeader.element.localName not in ("formula", "consistencyAssertion", "valueAssertion", "message"): raise XPathContext.XPathException( p, 'xffe:invalidFunctionUse', _('Function xff:uncovered-aspect cannot be used on an XPath expression associated with a {0}' ).format(xc.progHeader.element.localName)) if xc.variableSet and xc.variableSet.implicitFiltering == "false": raise XPathContext.XPathException( p, 'xffe:invalidFunctionUse', _('Function xff:uncovered-aspect cannot be used with implicitFiltering=false' )) if aspect == Aspect.DIMENSIONS: if qn: modelConcept = xc.modelXbrl.qnameConcepts.get(qn) if modelConcept and modelConcept.isDimensionItem: aspect = qn else: return () # not a dimension dimValue = uncoveredAspectValue(xc, aspect) if isinstance(dimValue, ModelObject.ModelDimensionValue): if dimValue.isExplicit: return dimValue.memberQname elif dimValue.isTyped: return dimValue.typedMember elif isinstance(dimValue, QName): # qname for explicit or node for typed return dimValue return () aspectValue = uncoveredAspectValue(xc, aspect) if aspectValue is None: return () return aspectValue
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
def error(xc, p, contextItem, args): if len(args) > 2: raise XPathContext.FunctionNumArgs() qn = qnameArg(xc, p, args, 0, 'QName?', emptyFallback=None) msg = stringArg(xc, args, 1, "xs:string", emptyFallback='') raise XPathContext.XPathException(p, (qn or "err:FOER0000"), msg)
def QName(xc, p, contextItem, args): if len(args) != 2: raise XPathContext.FunctionNumArgs() ns = stringArg(xc, args, 0, "xs:string?") prefixedName = stringArg(xc, args, 1, "xs:string") return qname(ns, prefixedName)
def resolve_uri(xc, p, contextItem, args): if len(args) != 2: raise XPathContext.FunctionNumArgs() relative = stringArg(xc, args, 0, "xs:string?", emptyFallback=()) base = stringArg(xc, args, 1, "xs:string", emptyFallback=()) return xc.modelXbrl.modelManager.cntlr.webCache.normalizeUrl(relative,base)
def replace(xc, p, contextItem, args): if len(args) != 3: raise XPathContext.FunctionNumArgs() input = stringArg(xc, args, 0, "xs:string?", emptyFallback=()) pattern = stringArg(xc, args, 1, "xs:string", emptyFallback=()) replacement = stringArg(xc, args, 1, "xs:string", emptyFallback=()) return input.replace(pattern,replacement)
def matches(xc, p, contextItem, args): if len(args) != 2: raise XPathContext.FunctionNumArgs() input = stringArg(xc, args, 0, "xs:string?", emptyFallback=()) pattern = stringArg(xc, args, 1, "xs:string", emptyFallback=()) return bool(re.match(pattern, input))
def matches(xc, p, contextItem, args): if len(args) != 2: raise XPathContext.FunctionNumArgs() input = stringArg(xc, args, 0, "xs:string?", emptyFallback=()) pattern = stringArg(xc, args, 1, "xs:string", emptyFallback=()) return bool(re.match(pattern,input))
def concept_relationships(xc, p, args): lenArgs = len(args) if lenArgs < 4 or lenArgs > 8: raise XPathContext.FunctionNumArgs() qnSource = qnameArg(xc, p, args, 0, 'QName', emptyFallback=None) linkroleURI = stringArg(xc, args, 1, "xs:string") if not linkroleURI: linkroleURI = XbrlConst.defaultLinkRole arcroleURI = stringArg(xc, args, 2, "xs:string") axis = stringArg(xc, args, 3, "xs:string") if not axis in ('descendant', 'child', 'ancestor', 'parent', 'sibling', 'sibling-or-self'): return () if qnSource != XbrlConst.qnXfiRoot: srcConcept = xc.modelXbrl.qnameConcepts.get(qnSource) if srcConcept is None: return () if lenArgs > 4: generations = numericArg(xc, p, args, 4, "xs:integer", convertFallback=0) elif axis in ('child', 'parent', 'sibling', 'sibling-or-self'): generations = 1 else: generations = 0 if axis in ('child','parent','sibling', 'sibling-or-self'): generations = 1 if axis == 'child': axis = 'descendant' elif axis == 'parent': axis = 'ancestor' if lenArgs > 5: qnLink = qnameArg(xc, p, args, 5, 'QName', emptyFallback=None) else: qnLink = None if lenArgs > 5: qnArc = qnameArg(xc, p, args, 6, 'QName', emptyFallback=None) else: qnArc = None removeSelf = axis == 'sibling' relationshipSet = xc.modelXbrl.relationshipSet(arcroleURI, linkroleURI, qnLink, qnArc) if relationshipSet: result = [] visited = {qnSource} if qnSource == XbrlConst.qnXfiRoot: if axis in ('sibling', 'sibling-or-self', 'ancestor'): return [] roots = relationshipSet.rootConcepts visited = {c.qname for c in roots} rels = [rel for c in roots for rel in relationshipSet.fromModelObject(c)] if generations == 1: return rels if generations > 1: generations -= 1 elif axis == 'descendant': rels = relationshipSet.fromModelObject(srcConcept) elif axis == 'ancestor': # includes first pass on parents of object to get sibling rels = relationshipSet.toModelObject(srcConcept) elif axis in ('sibling', 'sibling-or-self'): rels = relationshipSet.toModelObject(srcConcept) if rels: rels = relationshipSet.fromModelObject(rels[0].fromModelObject) axis = 'descendant' else: # must be a root, never has any siblings return [] if rels: concept_relationships_step(xc, relationshipSet, rels, axis, generations, result, visited) if removeSelf: for i, rel in enumerate(result): if rel.toModelObject == srcConcept: result.pop(i) break return result return ()
def encode_for_uri(xc, p, contextItem, args): from urllib.parse import quote if len(args) != 1: raise XPathContext.FunctionNumArgs() return quote(stringArg(xc, args, 0, "xs:string"))
def replace(xc, p, contextItem, args): if len(args) != 3: raise XPathContext.FunctionNumArgs() input = stringArg(xc, args, 0, "xs:string?", emptyFallback=()) pattern = stringArg(xc, args, 1, "xs:string", emptyFallback=()) replacement = stringArg(xc, args, 1, "xs:string", emptyFallback=()) return input.replace(pattern, replacement)
def lower_case(xc, p, contextItem, args): if len(args) != 1: raise XPathContext.FunctionNumArgs() return stringArg(xc, args, 0, "xs:string").lower()
def normalize_space(xc, p, contextItem, args): if len(args) > 1: raise XPathContext.FunctionNumArgs() return ' '.join( nonSpacePattern.findall( stringArg(xc, args, 0, "xs:string", missingArgFallback=contextItem) ) )
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=()) return bool(re.match(pattern, input, flags=regexFlags(xc, p, args, 2)))
def string_to_codepoints(xc, p, contextItem, args): if len(args) != 1: raise XPathContext.FunctionNumArgs() str = stringArg(xc, args, 0, "xs:string", emptyFallback=()) if str == (): return () return tuple(ord(c) for c in str)
def string_length(xc, p, contextItem, args): if len(args) > 1: raise XPathContext.FunctionNumArgs() return len( stringArg(xc, args, 0, "xs:string", missingArgFallback=contextItem) )
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 )