corriger le module python ulib.ext.xpath
This commit is contained in:
parent
62a59e51f4
commit
c552d2de56
|
@ -1,162 +1,2 @@
|
|||
from xpath.exceptions import *
|
||||
import xpath.exceptions
|
||||
import xpath.expr
|
||||
import xpath.parser
|
||||
import xpath.yappsrt
|
||||
|
||||
__all__ = ['find', 'findnode', 'findvalue', 'XPathContext', 'XPath']
|
||||
__all__.extend((x for x in dir(xpath.exceptions) if not x.startswith('_')))
|
||||
|
||||
def api(f):
|
||||
"""Decorator for functions and methods that are part of the external
|
||||
module API and that can throw XPathError exceptions.
|
||||
|
||||
The call stack for these exceptions can be very large, and not very
|
||||
interesting to the user. This decorator rethrows XPathErrors to
|
||||
trim the stack.
|
||||
|
||||
"""
|
||||
def api_function(*args, **kwargs):
|
||||
try:
|
||||
return f(*args, **kwargs)
|
||||
except XPathError, e:
|
||||
raise e
|
||||
api_function.__name__ = f.__name__
|
||||
api_function.__doc__ = f.__doc__
|
||||
return api_function
|
||||
|
||||
class XPathContext(object):
|
||||
def __init__(self, document=None, **kwargs):
|
||||
self.default_namespace = None
|
||||
self.namespaces = {}
|
||||
self.variables = {}
|
||||
|
||||
if document is not None:
|
||||
if document.nodeType != document.DOCUMENT_NODE:
|
||||
document = document.ownerDocument
|
||||
if document.documentElement is not None:
|
||||
attrs = document.documentElement.attributes
|
||||
for attr in (attrs.item(i) for i in xrange(attrs.length)):
|
||||
if attr.name == 'xmlns':
|
||||
self.default_namespace = attr.value
|
||||
elif attr.name.startswith('xmlns:'):
|
||||
self.namespaces[attr.name[6:]] = attr.value
|
||||
|
||||
self.update(**kwargs)
|
||||
|
||||
def clone(self):
|
||||
dup = XPathContext()
|
||||
dup.default_namespace = self.default_namespace
|
||||
dup.namespaces.update(self.namespaces)
|
||||
dup.variables.update(self.variables)
|
||||
return dup
|
||||
|
||||
def update(self, default_namespace=None, namespaces=None,
|
||||
variables=None, **kwargs):
|
||||
if default_namespace is not None:
|
||||
self.default_namespace = default_namespace
|
||||
if namespaces is not None:
|
||||
self.namespaces = namespaces
|
||||
if variables is not None:
|
||||
self.variables = variables
|
||||
self.variables.update(kwargs)
|
||||
|
||||
@api
|
||||
def find(self, expr, node, **kwargs):
|
||||
return xpath.find(expr, node, context=self, **kwargs)
|
||||
|
||||
@api
|
||||
def findnode(self, expr, node, **kwargs):
|
||||
return xpath.findnode(expr, node, context=self, **kwargs)
|
||||
|
||||
@api
|
||||
def findvalue(self, expr, node, **kwargs):
|
||||
return xpath.findvalue(expr, node, context=self, **kwargs)
|
||||
|
||||
@api
|
||||
def findvalues(self, expr, node, **kwargs):
|
||||
return xpath.findvalues(expr, node, context=self, **kwargs)
|
||||
|
||||
class XPath():
|
||||
_max_cache = 100
|
||||
_cache = {}
|
||||
|
||||
def __init__(self, expr):
|
||||
"""Init docs.
|
||||
"""
|
||||
try:
|
||||
parser = xpath.parser.XPath(xpath.parser.XPathScanner(str(expr)))
|
||||
self.expr = parser.XPath()
|
||||
except xpath.yappsrt.SyntaxError, e:
|
||||
raise XPathParseError(str(expr), e.pos, e.msg)
|
||||
|
||||
@classmethod
|
||||
def get(cls, s):
|
||||
if isinstance(s, cls):
|
||||
return s
|
||||
try:
|
||||
return cls._cache[s]
|
||||
except KeyError:
|
||||
if len(cls._cache) > cls._max_cache:
|
||||
cls._cache.clear()
|
||||
expr = cls(s)
|
||||
cls._cache[s] = expr
|
||||
return expr
|
||||
|
||||
@api
|
||||
def find(self, node, context=None, **kwargs):
|
||||
if context is None:
|
||||
context = XPathContext(node, **kwargs)
|
||||
elif kwargs:
|
||||
context = context.clone()
|
||||
context.update(**kwargs)
|
||||
return self.expr.evaluate(node, 1, 1, context)
|
||||
|
||||
@api
|
||||
def findnode(self, node, context=None, **kwargs):
|
||||
result = self.find(node, context, **kwargs)
|
||||
if not xpath.expr.nodesetp(result):
|
||||
raise XPathTypeError("expression is not a node-set")
|
||||
if len(result) == 0:
|
||||
return None
|
||||
return result[0]
|
||||
|
||||
@api
|
||||
def findvalue(self, node, context=None, **kwargs):
|
||||
result = self.find(node, context, **kwargs)
|
||||
if xpath.expr.nodesetp(result):
|
||||
if len(result) == 0:
|
||||
return None
|
||||
result = xpath.expr.string(result)
|
||||
return result
|
||||
|
||||
@api
|
||||
def findvalues(self, node, context=None, **kwargs):
|
||||
result = self.find(node, context, **kwargs)
|
||||
if not xpath.expr.nodesetp(result):
|
||||
raise XPathTypeError("expression is not a node-set")
|
||||
return [xpath.expr.string_value(x) for x in result]
|
||||
|
||||
def __repr__(self):
|
||||
return '%s.%s(%s)' % (self.__class__.__module__,
|
||||
self.__class__.__name__,
|
||||
repr(str(self.expr)))
|
||||
|
||||
def __str__(self):
|
||||
return str(self.expr)
|
||||
|
||||
@api
|
||||
def find(expr, node, **kwargs):
|
||||
return XPath.get(expr).find(node, **kwargs)
|
||||
|
||||
@api
|
||||
def findnode(expr, node, **kwargs):
|
||||
return XPath.get(expr).findnode(node, **kwargs)
|
||||
|
||||
@api
|
||||
def findvalue(expr, node, **kwargs):
|
||||
return XPath.get(expr).findvalue(node, **kwargs)
|
||||
|
||||
@api
|
||||
def findvalues(expr, node, **kwargs):
|
||||
return XPath.get(expr).findvalues(node, **kwargs)
|
||||
from main import __all__
|
||||
from main import *
|
||||
|
|
|
@ -6,8 +6,7 @@ import re
|
|||
import xml.dom
|
||||
import weakref
|
||||
|
||||
from xpath.exceptions import *
|
||||
import xpath
|
||||
from exceptions import *
|
||||
|
||||
|
||||
#
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
from exceptions import *
|
||||
import exceptions
|
||||
import expr
|
||||
import parser
|
||||
import yappsrt
|
||||
|
||||
class MODULE: pass
|
||||
XPATH = MODULE()
|
||||
XPATH.exceptions = exceptions
|
||||
XPATH.expr = expr
|
||||
XPATH.parser = parser
|
||||
XPATH.yappsrt = yappsrt
|
||||
|
||||
__all__ = ['find', 'findnode', 'findvalue', 'XPathContext', 'XPath']
|
||||
__all__.extend((x for x in dir(XPATH.exceptions) if not x.startswith('_')))
|
||||
|
||||
def api(f):
|
||||
"""Decorator for functions and methods that are part of the external
|
||||
module API and that can throw XPathError exceptions.
|
||||
|
||||
The call stack for these exceptions can be very large, and not very
|
||||
interesting to the user. This decorator rethrows XPathErrors to
|
||||
trim the stack.
|
||||
|
||||
"""
|
||||
def api_function(*args, **kwargs):
|
||||
try:
|
||||
return f(*args, **kwargs)
|
||||
except XPathError, e:
|
||||
raise e
|
||||
api_function.__name__ = f.__name__
|
||||
api_function.__doc__ = f.__doc__
|
||||
return api_function
|
||||
|
||||
class XPathContext(object):
|
||||
def __init__(self, document=None, **kwargs):
|
||||
self.default_namespace = None
|
||||
self.namespaces = {}
|
||||
self.variables = {}
|
||||
|
||||
if document is not None:
|
||||
if document.nodeType != document.DOCUMENT_NODE:
|
||||
document = document.ownerDocument
|
||||
if document.documentElement is not None:
|
||||
attrs = document.documentElement.attributes
|
||||
for attr in (attrs.item(i) for i in xrange(attrs.length)):
|
||||
if attr.name == 'xmlns':
|
||||
self.default_namespace = attr.value
|
||||
elif attr.name.startswith('xmlns:'):
|
||||
self.namespaces[attr.name[6:]] = attr.value
|
||||
|
||||
self.update(**kwargs)
|
||||
|
||||
def clone(self):
|
||||
dup = XPathContext()
|
||||
dup.default_namespace = self.default_namespace
|
||||
dup.namespaces.update(self.namespaces)
|
||||
dup.variables.update(self.variables)
|
||||
return dup
|
||||
|
||||
def update(self, default_namespace=None, namespaces=None,
|
||||
variables=None, **kwargs):
|
||||
if default_namespace is not None:
|
||||
self.default_namespace = default_namespace
|
||||
if namespaces is not None:
|
||||
self.namespaces = namespaces
|
||||
if variables is not None:
|
||||
self.variables = variables
|
||||
self.variables.update(kwargs)
|
||||
|
||||
@api
|
||||
def find(self, expr, node, **kwargs):
|
||||
return XPATH.find(expr, node, context=self, **kwargs)
|
||||
|
||||
@api
|
||||
def findnode(self, expr, node, **kwargs):
|
||||
return XPATH.findnode(expr, node, context=self, **kwargs)
|
||||
|
||||
@api
|
||||
def findvalue(self, expr, node, **kwargs):
|
||||
return XPATH.findvalue(expr, node, context=self, **kwargs)
|
||||
|
||||
@api
|
||||
def findvalues(self, expr, node, **kwargs):
|
||||
return XPATH.findvalues(expr, node, context=self, **kwargs)
|
||||
|
||||
class XPath():
|
||||
_max_cache = 100
|
||||
_cache = {}
|
||||
|
||||
def __init__(self, expr):
|
||||
"""Init docs.
|
||||
"""
|
||||
try:
|
||||
parser = XPATH.parser.XPath(XPATH.parser.XPathScanner(str(expr)))
|
||||
self.expr = parser.XPath()
|
||||
except XPATH.yappsrt.SyntaxError, e:
|
||||
raise XPathParseError(str(expr), e.pos, e.msg)
|
||||
|
||||
@classmethod
|
||||
def get(cls, s):
|
||||
if isinstance(s, cls):
|
||||
return s
|
||||
try:
|
||||
return cls._cache[s]
|
||||
except KeyError:
|
||||
if len(cls._cache) > cls._max_cache:
|
||||
cls._cache.clear()
|
||||
expr = cls(s)
|
||||
cls._cache[s] = expr
|
||||
return expr
|
||||
|
||||
@api
|
||||
def find(self, node, context=None, **kwargs):
|
||||
if context is None:
|
||||
context = XPathContext(node, **kwargs)
|
||||
elif kwargs:
|
||||
context = context.clone()
|
||||
context.update(**kwargs)
|
||||
return self.expr.evaluate(node, 1, 1, context)
|
||||
|
||||
@api
|
||||
def findnode(self, node, context=None, **kwargs):
|
||||
result = self.find(node, context, **kwargs)
|
||||
if not XPATH.expr.nodesetp(result):
|
||||
raise XPathTypeError("expression is not a node-set")
|
||||
if len(result) == 0:
|
||||
return None
|
||||
return result[0]
|
||||
|
||||
@api
|
||||
def findvalue(self, node, context=None, **kwargs):
|
||||
result = self.find(node, context, **kwargs)
|
||||
if XPATH.expr.nodesetp(result):
|
||||
if len(result) == 0:
|
||||
return None
|
||||
result = XPATH.expr.string(result)
|
||||
return result
|
||||
|
||||
@api
|
||||
def findvalues(self, node, context=None, **kwargs):
|
||||
result = self.find(node, context, **kwargs)
|
||||
if not XPATH.expr.nodesetp(result):
|
||||
raise XPathTypeError("expression is not a node-set")
|
||||
return [XPATH.expr.string_value(x) for x in result]
|
||||
|
||||
def __repr__(self):
|
||||
return '%s.%s(%s)' % (self.__class__.__module__,
|
||||
self.__class__.__name__,
|
||||
repr(str(self.expr)))
|
||||
|
||||
def __str__(self):
|
||||
return str(self.expr)
|
||||
|
||||
@api
|
||||
def find(expr, node, **kwargs):
|
||||
return XPath.get(expr).find(node, **kwargs)
|
||||
|
||||
@api
|
||||
def findnode(expr, node, **kwargs):
|
||||
return XPath.get(expr).findnode(node, **kwargs)
|
||||
|
||||
@api
|
||||
def findvalue(expr, node, **kwargs):
|
||||
return XPath.get(expr).findvalue(node, **kwargs)
|
||||
|
||||
@api
|
||||
def findvalues(expr, node, **kwargs):
|
||||
return XPath.get(expr).findvalues(node, **kwargs)
|
|
@ -1,5 +1,5 @@
|
|||
import xpath.expr as X
|
||||
from xpath.yappsrt import *
|
||||
import expr as X
|
||||
from yappsrt import *
|
||||
|
||||
|
||||
from string import *
|
||||
|
|
Loading…
Reference in New Issue