Beispiel #1
0
def Split(context, string, pattern=u' '):
    '''
    Similar to Ft.Xml.Xslt.Exslt.String.Split but does not depend
    on a XSLT processor -- any XPath context will do.    
    '''
    string = StringValue(string)
    pattern = StringValue(pattern)
    nodeset = []

    frag = context.node.ownerDocument.createDocumentFragment()

    def addToNodeset(token):
        text = context.node.ownerDocument.createTextNode(token)
        nodeset.append(text)
        return
        #the following causes a seg fault in cdomlette the second time around
        elem = context.node.ownerDocument.createElementNS(None, 'token')
        frag.appendChild(elem)
        text = context.node.ownerDocument.createTextNode(token)
        elem.appendChild(text)
        nodeset.append(elem)

    if pattern:
        if string:
            if pattern == ' ':
                pattern = None  #python normalizes whitespace if pattern is None
            #addToNodeset(string.split(pattern)[0])
            for token in string.split(pattern):
                addToNodeset(token)
    else:
        for ch in string:
            addToNodeset(token)
    return nodeset
Beispiel #2
0
    def Id(context, object):
        """Function: <node-set> id(<object>)"""
        id_list = []
        if type(object) != type([]):
            st = StringValue(object)
            id_list = st.split()
        else:
            for n in object:
                id_list.append(StringValue(n))

        doc = context.node.rootNode
        getElementById = getattr(doc, 'getElementById', None)
        if not getElementById:
            #this is from 4suite 1.0a3's version of id():
            import warnings
            warnings.warn("id() function not supported")
            #We do not (cannot, really) support the id() function
            return []

        nodeset = []
        for id in id_list:
            element = getElementById(id)
            if element:
                nodeset.append(element)
        return Set.Unique(nodeset)
Beispiel #3
0
def ParseDateToPyTime(context, date, format=''):
    """
    Inverse of CurrentTime
    """
    import calendar
    date = StringValue(date)
    format = StringValue(format) or "%Y-%m-%dT%H:%M:%S"
    time_tuple = time.strptime(date, format)
    return "%.3f" % calendar.timegm(time_tuple)
Beispiel #4
0
def ParseRDF(context, contents, type='unknown', uri=''):
    contents = StringValue(contents)
    type = StringValue(type)
    uri = StringValue(uri)
    if not uri:
        from Ft.Lib import Uuid
        uri = 'urn:uuid:' + Uuid.UuidAsString(Uuid.GenerateUuid())
    nsRevMap = getattr(context.node.ownerDocument, 'nsRevMap', None)
    schemaClass = getattr(context.node.ownerDocument, 'schemaClass',
                          RxPath.defaultSchemaClass)
    stmts = RxPath.parseRDFFromString(contents, uri, type)
    return [RxPath.RxPathDOMFromStatements(stmts, nsRevMap, uri, schemaClass)]
Beispiel #5
0
def Test(tester):
    
    tester.startTest("CDATA Conversions")
    isrc = InputSource.DefaultFactory.fromString(test,'rs')
    dom = tester.test_data['parse'](isrc)
    NormalizeNode(dom)
    nodes = Evaluate('//bar/text()', contextNode = dom)
    tester.compare(2,len(nodes))
    tester.compare('normal text',StringValue(nodes[0]))
    tester.compare('<cdatatext>',StringValue(nodes[1]))
    tester.compare('<cdatatext>',Evaluate('string(//bar[2]/text())', contextNode = dom))
    tester.testDone()
Beispiel #6
0
 def _getNamesFromURI(context, uri=None):
     if uri is None:
         uri = context.node
     uri = StringValue(uri)
     qname, namespaceURI, prefix, localName = \
         elementNamesFromURI(uri, context.node.ownerDocument.nsRevMap)
     return qname, namespaceURI, prefix, localName
Beispiel #7
0
def Map(context, nodeset, string):
    if type(nodeset) != type([]):
        raise RuntimeException(RuntimeException.WRONG_ARGUMENTS, 'map',
                               "expected node set argument")
    from Ft.Xml.XPath import parser
    from Ft.Lib import Set
    from rx import raccoon
    mapContext = context.clone()
    mapContext.size = len(nodeset)
    mapContext.position = 1
    #note: exslt-dyn:map implies that parse exception should be caught and an empty nodeset returned
    expCache = raccoon.RequestProcessor.expCache
    xpath = StringValue(string)
    queryCache = getattr(context.node.ownerDocument, 'queryCache', None)

    def eval(l, node):
        mapContext.node = node
        mapContext.position += 1
        mapContext.varBindings[(RXWIKI_XPATH_EXT_NS, 'current')] = node
        result = RxPath.evalXPath(xpath, mapContext, expCache, queryCache)
        if type(result) != type([]):
            if not isinstance(result, unicode):
                result = unicode(str(result), 'utf8')
            result = String2NodeSet(mapContext, result)
        l.extend(result)
        return l

    nodeset = reduce(eval, nodeset, [])
    return Set.Unique(nodeset)
Beispiel #8
0
    def getURIFromElement(context, nodeset=None):
        string = None
        if nodeset is None:
            node = context.node
        elif type(nodeset) == type([]):
            if nodeset:
                node = nodeset[0]
                if node.nodeType != Node.ELEMENT_NODE:
                    string = node
            else:
                return u''
        else:
            string = nodeset

        if string is not None:
            qname = StringValue(string)
            (prefix, local) = SplitQName(qname)
            if prefix:
                try:
                    namespace = context.processorNss[prefix]
                except KeyError:
                    raise XPath.RuntimeException(
                        XPath.RuntimeException.UNDEFINED_PREFIX, prefix)
                return namespace + getURIFragmentFromLocal(local)
        else:
            return getURIFromElementName(node)
Beispiel #9
0
 def isType(context, candidate, test):
     '''    
     This function returns true if the class specified in the first
     argument is a subtype of the class specified in the second
     argument, where each string is treated as the URI reference of a
     class resource.
     '''
     #design note: follow equality semantics for nodesets
     if not isinstance(test, list):
         test = [test]
     if not isinstance(candidate, list):
         candidate = [candidate]
     for node in test:
         classURI = StringValue(node)
         for candidateNode in candidate:
             if context.node.ownerDocument.schema.isCompatibleType(
                     StringValue(candidateNode), classURI):
                 return XTrue
     return XFalse
Beispiel #10
0
 def isInstanceOf(context, candidate, test):
     '''
     This function returns true if the resource specified in the first
     argument is an instance of the class resource specified in the
     second argument, where each string is treated as the URI reference
     of a resource.
     '''
     #design note: follow equality semantics for nodesets
     if not isinstance(test, list):
         test = [test]
     if not isinstance(candidate, list):
         candidate = [candidate]
     for node in test:
         classResource = StringValue(node)
         for candidateNode in candidate:
             resource = context.node.ownerDocument.findSubject(
                 StringValue(candidateNode))
             if resource and resource.matchName(classResource, ''):
                 return XTrue
     return XFalse
Beispiel #11
0
def SystemProperty(context, qname):
    '''
    disable the 'http://xmlns.4suite.org/xslt/env-system-property'
    namespace (it is a security hole), otherwise call
    Ft.Xml.Xslt.XsltFunctions.SystemProperty
    '''
    qname = StringValue(qname)
    if qname:
        (uri, local) = context.expandQName(qname)
        if uri == 'http://xmlns.4suite.org/xslt/env-system-property':
            return u''
    return XsltFunctions.SystemProperty(context, qname)
Beispiel #12
0
def FileExists(context, uri):
    path = StringValue(uri)
    if path.startswith('file:'):
        path = Uri.UriToOsPath(path)  #todo: security hole
        return Xbool(os.path.exists(path))
    else:
        if path.startswith('path:'):
            path = path[len('path:'):]
        for prefix in InputSource.DefaultFactory.resolver.path:
            if os.path.exists(os.path.join(prefix.strip(), path)):
                return XTrue
        return XFalse
Beispiel #13
0
def FormatPyTime(context, t, format='%Y-%m-%dT%H:%M:%S'):
    """
    Given a Python timestamp number return a formatted date string.
        t - a time stamp number, as from Python's time.time()
            if omitted, use the current time
        format - Python date format
    """
    if t:
        t = NumberValue(t)
        t = time.gmtime(t)
    else:
        t = time.gmtime()
    return time.strftime(StringValue(format), t)
Beispiel #14
0
def SerializeRDF(context,
                 resultset,
                 type='rdfxml',
                 nsMapString=None,
                 fixUp=None,
                 fixUpPredicate=None):
    '''Returns a nodeset containing a RDF serialization of the
  RxPathDOM nodes contained in resultset parameter.
  
  nsMapString is a namespace dictionary encoded as a string in the form of "prefix^uri^prefix^uri..."
  
  '''
    stmts = []
    uri2prefixMap = None
    if nsMapString:
        import itertools
        nslist = StringValue(nsMapString).split('^')
        uri2prefixMap = dict(
            itertools.izip(itertools.islice(nslist, 1, None, 2),
                           itertools.islice(nslist, 0, None, 2)))
    if resultset:
        if uri2prefixMap is None:
            uri2prefixMap = resultset[0].rootNode.nsRevMap
        if resultset[0].nodeName == '#document':
            resultset = resultset[0].childNodes

        for n in resultset:
            nl = [n]
            if RxPath.isResource(context, nl):
                preds = n.childNodes
            elif RxPath.isPredicate(context, nl):
                preds = nl
            else:
                preds = []  #error?

            for p in preds:
                stmts.extend(p.getModelStatements())
                if (RxPath.isResource(context, p.childNodes)
                        and p.firstChild.isCompound()):
                    #object is a list so add all the list items too
                    stmts.extend(p.firstChild.getModelStatements())

    return RxPath.serializeRDF(stmts, type, uri2prefixMap, fixUp,
                               fixUpPredicate)
Beispiel #15
0
def instanceof(context, test, cmptype):
    '''sort of like the "instance of" operator in XPath 2.0'''
    #todo: do we really need this when there is exsl:object-type
    cmptype = StringValue(cmptype)
    if cmptype == 'number':
        result = isinstance(test, (int, float))  #float
    elif cmptype == 'string':
        result = isinstance(test, (unicode, str))  #string
    elif cmptype == 'node-set':
        result = isinstance(test, list)  #node-set
    elif cmptype == 'boolean':
        #result = isinstance(test, (bool, XPath.boolean.BooleanType)) #boolean
        result = test == 1 or test == 0
    elif cmptype == 'object':
        #true if any thing is not one of the above types
        result = not isinstance(test, (int, float, unicode, str, list, bool,
                                       XPath.boolean.BooleanType))  #boolean
    else:
        raise RuntimeError('unknown type specified %s' % cmptype)
    return Xbool(result)
Beispiel #16
0
def DocumentAsText(context, url):
    '''
    Return the contents of url as a string or an empty nodeset
    if url is an zero length string. If the url resolves to a file
    thCat contains bytes sequences that are not ascii or utf-8
    (e.g. a binary file) this function can not be used in contexts
    such as xsl:value-of however, an raw xpath expression will
    return a non-unicode string and thus will work in those
    contexts.
    '''

    urlString = StringValue(url)
    if not urlString:
        return []  #return an empty nodeset
    #todo: set baseURI = this current context's $_path,
    #have site resolver use this as the docbase
    file = InputSource.DefaultFactory.fromUri(urlString)
    bytes = file.read()
    file.close()
    #print 'bytes', bytes[0:100]
    return bytes
Beispiel #17
0
    def rdfDocument(context, object, type='unknown', nodeset=None):
        '''Equivalent to XSLT's document() function except it parses RDF
        and returns RxPath Document nodes instead of XML Document nodes.
        The first and third arguments are equivalent to document()'s first
        and second arguments, respectively, and the second argument is
        converted to a string that names the format of the RDF being
        parsed. The format names recognized are the same as the ones used
        by parseRDFFromString(). ParseException will be raised if the RDF
        can not be parsed.
    
        Note: this is only available in the context of an XSLT processor.
        '''

        type = StringValue(type)
        oldDocReader = context.processor._docReader

        class RDFDocReader:
            def __init__(self, uri2prefixMap, type, schemaClass):
                self.uri2prefixMap = uri2prefixMap
                self.type = type
                self.schemaClass = schemaClass

            def parse(self, isrc):
                contents = isrc.stream.read()
                isrc.stream.close()
                stmts = parseRDFFromString(contents, isrc.uri, self.type)
                return RxPathDOMFromStatements(stmts, self.uri2prefixMap,
                                               isrc.uri, self.schemaClass)

        nsRevMap = getattr(context.node.ownerDocument, 'nsRevMap', None)
        schemaClass = getattr(context.node.ownerDocument, 'schemaClass',
                              defaultSchemaClass)
        context.processor._docReader = RDFDocReader(nsRevMap, type,
                                                    defaultSchemaClass)
        from Ft.Xml.Xslt import XsltFunctions
        result = XsltFunctions.Document(context, object, nodeset)
        context.processor._docReader = oldDocReader
        return result
Beispiel #18
0
def addRxdom2Model(rootNode, model, rdfdom=None, thisResource=None, scope=''):
    '''given a DOM of a RXML document, iterate through it, adding its statements to the specified 4Suite model    
    Note: no checks if the statement is already in the model
    '''
    nsMap = {None: RX_NS, 'rx': RX_NS}
    #todo: bug! revNsMap doesn't work with 2 prefixes one ns
    #revNsMap = dict(map(lambda x: (x[1], x[0]), nsMap.items()) )#reverse namespace map
    #rxNSPrefix = revNsMap[RX_NS]
    rxNSPrefix = [x[0] for x in nsMap.items() if x[1] == RX_NS]
    if not rxNSPrefix:  #if RX_NS is missing from the nsMap add the 'rx' prefix if not already specified
        rxNSPrefix = []
        if not nsMap.get('rx'):
            nsMap['rx'] = RX_NS
            rxNSPrefix.append('rx')
        #if no default prefix was set, also make RX_NS the default
        if None not in nsMap:
            nsMap[None] = RX_NS
            rxNSPrefix.append(None)
    if not nsMap.get('rdf'):
        nsMap['rdf'] = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'
    if not nsMap.get('rdfs'):
        nsMap['rdfs'] = 'http://www.w3.org/2000/01/rdf-schema#'

    for s in rootNode.childNodes:
        if s.nodeType != s.ELEMENT_NODE:
            continue
        if matchName(s, rxNSPrefix, 'rx'):  #optional root element
            rootNode = s
        else:
            break

    for s in rootNode.childNodes:
        if s.nodeType != s.ELEMENT_NODE:
            continue

        if matchName(s, rxNSPrefix, 'prefixes'):
            for nsElem in s.childNodes:
                if nsElem.nodeType != nsElem.ELEMENT_NODE:
                    continue
                if matchName(nsElem, rxNSPrefix, RX_META_DEFAULT):
                    ns = None  #''
                else:
                    ns = nsElem.localName
                from Ft.Xml.XPath.Conversions import StringValue
                nsMap[ns] = StringValue(nsElem).strip()
                #revNsMap[nsElem.stringValue] = ns
            continue
        elif matchName(s, rxNSPrefix, 'res-query'):
            assert rdfdom
            if rdfdom:
                result = rdfdom.evalXPath(
                    s.getAttributeNS(EMPTY_NAMESPACE, 'id'), nsMap)
                if isinstance(result, (type(''), type(u''))):
                    resources = [result]
                else:
                    resources = map(
                        lambda x: x.getAttributeNS(RDF_MS_BASE, 'about'),
                        result)
            else:
                resources = []
        else:
            resource, typeName = getResource(s, rxNSPrefix, nsMap,
                                             thisResource)
            if typeName:
                model.addStatement(
                    Statement(resource, RDF_MS_BASE + 'type', typeName,
                              OBJECT_TYPE_RESOURCE, scope))
            resources = [resource]
        for resource in resources:
            addResource(model, scope, resource, s, rxNSPrefix, nsMap,
                        thisResource,
                        len(resources) > 1)
    return nsMap
Beispiel #19
0
def GenerateBnode(context, name=None):
    if name is not None:
        name = StringValue(name)
    return RxPath.generateBnode(name)
Beispiel #20
0
if BuiltInExtFunctions.ExtFunctions.has_key((FT_EXT_NAMESPACE, 'spawnv')):
    for functionDict in extFuncDicts:
        del functionDict[(FT_EXT_NAMESPACE, 'spawnv')]
        del functionDict[(FT_EXT_NAMESPACE, 'system')]
        del functionDict[(FT_EXT_NAMESPACE, 'env-var')]

#1.0a4 version of 4Suite deleted deprecated functions, so re-add the ones we still use
if not BuiltInExtFunctions.ExtFunctions.has_key(
    (FT_EXT_NAMESPACE, 'escape-url')):
    for functionDict in extFuncDicts:
        #4Suite 1.0a4's pytime-to-exslt is broken, reimplement it:
        functionDict[(FT_EXT_NAMESPACE, 'pytime-to-exslt')] = lambda context, t=None:\
            t and unicode(Time.FromPythonTime(NumberValue(t))) or unicode(Time.FromPythonTime())
        #todo: we should stop using this and use exslt:string's encode-uri
        functionDict[(FT_EXT_NAMESPACE, 'escape-url'
                      )] = lambda context, uri: urllib.quote(StringValue(uri))

if Exslt.ExtElements.has_key(("http://exslt.org/common", 'document')):
    #document only can write to the local files system and does use our secure URI resolver
    del Exslt.ExtElements[("http://exslt.org/common", 'document')]


def SystemProperty(context, qname):
    '''
    disable the 'http://xmlns.4suite.org/xslt/env-system-property'
    namespace (it is a security hole), otherwise call
    Ft.Xml.Xslt.XsltFunctions.SystemProperty
    '''
    qname = StringValue(qname)
    if qname:
        (uri, local) = context.expandQName(qname)