'Replaces tags in `query` with property values.
Parameters
query : str
String with tags.
aInfo : dict
Tags(keys) and associated values for substitution in query.
Returns
str
`query` string with tags replaced.'

@classmethod
def replaceTag(cls, query, aInfo, conditional='', cache=None):

    if ('<' not in query):
        return query
    if (cache is not None):
        ckey = (query, conditional)
        try:
            return cache[ckey]
        except KeyError:
            pass
    noRecRepl = isinstance(aInfo, CallingMap)
    subInfo = aInfo
    if (not noRecRepl):
        subInfo = csubkey = None
        if (cache is not None):
            csubkey = ('subst-tags', id(aInfo), conditional)
            try:
                subInfo = cache[csubkey]
            except KeyError:
                pass
        if (subInfo is None):
            subInfo = substituteRecursiveTags(aInfo, conditional, ignore=cls._escapedTags)
        if (csubkey is not None):
            cache[csubkey] = subInfo
    def substVal(m):
        tag = m.group(1)
        value = None
        if conditional:
            value = subInfo.get(((tag + '?') + conditional))
        if (value is None):
            value = subInfo.get(tag)
            if (value is None):
                return ADD_REPL_TAGS.get(tag, m.group())
        value = str(value)
        if (tag in cls._escapedTags):
            value = cls.escapeTag(value)
        return value
    count = (MAX_TAG_REPLACE_COUNT + 1)
    while True:
        value = TAG_CRE.sub(substVal, query)
        if noRecRepl:
            break
        if ((value == query) or ('<' not in value)):
            break
        query = value
        count -= 1
        if (count <= 0):
            raise ValueError(('unexpected    too    long    replacement    interpolation,    possible    self    referencing    definitions    in    query:    %s' % (query,)))
    if (cache is not None):
        cache[ckey] = value
    return value
