corriger le module python ulib.ext.xpath
This commit is contained in:
parent
62a59e51f4
commit
c552d2de56
|
@ -1,162 +1,2 @@
|
||||||
from xpath.exceptions import *
|
from main import __all__
|
||||||
import xpath.exceptions
|
from main import *
|
||||||
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)
|
|
||||||
|
|
|
@ -6,8 +6,7 @@ import re
|
||||||
import xml.dom
|
import xml.dom
|
||||||
import weakref
|
import weakref
|
||||||
|
|
||||||
from xpath.exceptions import *
|
from exceptions import *
|
||||||
import xpath
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -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
|
import expr as X
|
||||||
from xpath.yappsrt import *
|
from yappsrt import *
|
||||||
|
|
||||||
|
|
||||||
from string import *
|
from string import *
|
||||||
|
|
Loading…
Reference in New Issue