summaryrefslogtreecommitdiff
path: root/src/lxml/classlookup.pxi
diff options
context:
space:
mode:
authorscoder <none@none>2008-02-28 18:37:18 +0100
committerscoder <none@none>2008-02-28 18:37:18 +0100
commit74960ada1f3a7398ed399fc4ad0c83cb9a8b1d51 (patch)
treeb8aeed6a215a2fb6b10ae69d6b0d0bd9313a4884 /src/lxml/classlookup.pxi
parent53142689bfffa15da9478b3d75be039d3f3e48c1 (diff)
downloadpython-lxml-74960ada1f3a7398ed399fc4ad0c83cb9a8b1d51.tar.gz
[svn r3363] r3641@delle: sbehnel | 2008-02-27 10:52:36 +0100
moved read-only tree implementation from lxml.pyclasslookup into lxml.etree --HG-- branch : trunk rename : src/lxml/lxml.pyclasslookup.pyx => src/lxml/readonlytree.pxi
Diffstat (limited to 'src/lxml/classlookup.pxi')
-rw-r--r--src/lxml/classlookup.pxi82
1 files changed, 81 insertions, 1 deletions
diff --git a/src/lxml/classlookup.pxi b/src/lxml/classlookup.pxi
index b1edfa41..948be451 100644
--- a/src/lxml/classlookup.pxi
+++ b/src/lxml/classlookup.pxi
@@ -119,7 +119,7 @@ cdef public class FallbackElementClassLookup(ElementClassLookup) \
################################################################################
-# Custom Element class lookup schemes
+# default lookup scheme
cdef class ElementDefaultClassLookup(ElementClassLookup):
"""ElementDefaultClassLookup(self, element=None, comment=None, pi=None, entity=None)
@@ -196,6 +196,10 @@ cdef object _lookupDefaultElementClass(state, _Document _doc, xmlNode* c_node):
else:
assert 0, "Unknown node type: %s" % c_node.type
+
+################################################################################
+# attribute based lookup scheme
+
cdef class AttributeBasedElementClassLookup(FallbackElementClassLookup):
"""AttributeBasedElementClassLookup(self, attribute_name, class_mapping, fallback=None)
Checks an attribute of an Element and looks up the value in a
@@ -241,6 +245,9 @@ cdef object _attribute_class_lookup(state, _Document doc, xmlNode* c_node):
return lookup._callFallback(doc, c_node)
+################################################################################
+# per-parser lookup scheme
+
cdef class ParserBasedElementClassLookup(FallbackElementClassLookup):
"""ParserBasedElementClassLookup(self, fallback=None)
Element class lookup based on the XML parser.
@@ -256,6 +263,9 @@ cdef object _parser_class_lookup(state, _Document doc, xmlNode* c_node):
return (<FallbackElementClassLookup>state)._callFallback(doc, c_node)
+################################################################################
+# custom class lookup based on node type, namespace, name
+
cdef class CustomElementClassLookup(FallbackElementClassLookup):
"""CustomElementClassLookup(self, fallback=None)
Element class lookup based on a subclass method.
@@ -313,6 +323,76 @@ cdef object _custom_class_lookup(state, _Document doc, xmlNode* c_node):
################################################################################
+# read-only tree based class lookup
+
+cdef class PythonElementClassLookup(FallbackElementClassLookup):
+ """PythonElementClassLookup(self, fallback=None)
+ Element class lookup based on a subclass method.
+
+ This class lookup scheme allows access to the entire XML tree in
+ read-only mode. To use it, re-implement the ``lookup(self, doc,
+ root)`` method in a subclass::
+
+ >>> from lxml import etree, pyclasslookup
+ >>>
+ >>> class MyElementClass(etree.ElementBase):
+ ... honkey = True
+ ...
+ >>> class MyLookup(pyclasslookup.PythonElementClassLookup):
+ ... def lookup(self, doc, root):
+ ... if root.tag == "sometag":
+ ... return MyElementClass
+ ... else:
+ ... for child in root:
+ ... if child.tag == "someothertag":
+ ... return MyElementClass
+ ... # delegate to default
+ ... return None
+
+ If you return None from this method, the fallback will be called.
+
+ The first argument is the opaque document instance that contains
+ the Element. The second argument is a lightweight Element proxy
+ implementation that is only valid during the lookup. Do not try
+ to keep a reference to it. Once the lookup is done, the proxy
+ will be invalid.
+
+ Also, you cannot wrap such a read-only Element in an ElementTree,
+ and you must take care not to keep a reference to them outside of
+ the `lookup()` method.
+
+ Note that the API of the Element objects is not complete. It is
+ purely read-only and does not support all features of the normal
+ `lxml.etree` API (such as XPath, extended slicing or some
+ iteration methods).
+
+ See http://codespeak.net/lxml/element_classes.html
+ """
+ def __init__(self, ElementClassLookup fallback=None):
+ FallbackElementClassLookup.__init__(self, fallback)
+ self._lookup_function = _python_class_lookup
+
+ def lookup(self, doc, element):
+ """lookup(self, doc, element)
+
+ Override this method to implement your own lookup scheme.
+ """
+ return None
+
+cdef object _python_class_lookup(state, _Document doc, tree.xmlNode* c_node):
+ cdef PythonElementClassLookup lookup
+ cdef _ReadOnlyElementProxy proxy
+ lookup = <PythonElementClassLookup>state
+
+ proxy = _newReadOnlyProxy(None, c_node)
+ cls = lookup.lookup(doc, proxy)
+ _freeReadOnlyProxies(proxy)
+
+ if cls is not None:
+ return cls
+ return lookup._callFallback(doc, c_node)
+
+################################################################################
# Global setup
cdef _element_class_lookup_function LOOKUP_ELEMENT_CLASS