capi.txt 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. ==============================
  2. The public C-API of lxml.etree
  3. ==============================
  4. As of version 1.1, lxml.etree provides a public C-API. This allows external
  5. C extensions to efficiently access public functions and classes of lxml,
  6. without going through the Python API.
  7. The API is described in the file `etreepublic.pxd`_, which is directly
  8. c-importable by extension modules implemented in Cython_.
  9. .. _`etreepublic.pxd`: https://github.com/lxml/lxml/blob/master/src/lxml/includes/etreepublic.pxd
  10. .. _Cython: https://cython.org
  11. .. contents::
  12. ..
  13. 1 Passing generated trees through Python
  14. 2 Writing external modules in Cython
  15. 3 Writing external modules in C
  16. Passing generated trees through Python
  17. --------------------------------------
  18. This is the most simple way to integrate with lxml. It does not require
  19. any C-level integration but uses a Python function to wrap an externally
  20. generated libxml2 document in lxml.
  21. The external module that creates the libxml2 tree must pack the document
  22. pointer into a `PyCapsule <https://docs.python.org/3/c-api/capsule.html>`_
  23. object. This can then be passed into lxml with the function
  24. ``lxml.etree.adopt_external_document()``. It also takes an optional lxml
  25. parser instance to associate with the document, in order to configure the
  26. Element class lookup, relative URL lookups, etc.
  27. See the `API reference <api/lxml.etree-module.html#adopt_external_document>`_
  28. for further details.
  29. The same functionality is available as part of the public C-API in form
  30. of the C function ``adoptExternalDocument()``.
  31. Writing external modules in Cython
  32. ----------------------------------
  33. This is the easiest way of extending lxml at the C level. A Cython_
  34. module should start like this::
  35. # My Cython extension
  36. # directive pointing compiler to lxml header files;
  37. # use ``aliases={"LXML_PACKAGE_DIR": lxml.__path__}``
  38. # argument to cythonize in setup.py to dynamically
  39. # determine dir at compile time
  40. # distutils: include_dirs = LXML_PACKAGE_DIR
  41. # import the public functions and classes of lxml.etree
  42. cimport lxml.includes.etreepublic as cetree
  43. # import the lxml.etree module in Python
  44. cdef object etree
  45. from lxml import etree
  46. # initialize the access to the C-API of lxml.etree
  47. cetree.import_lxml__etree()
  48. From this line on, you can access all public functions of lxml.etree
  49. from the ``cetree`` namespace like this::
  50. # build a tag name from namespace and element name
  51. py_tag = cetree.namespacedNameFromNsName("http://some/url", "myelement")
  52. Public lxml classes are easily subclassed. For example, to implement
  53. and set a new default element class, you can write Cython code like
  54. the following::
  55. from lxml.includes.etreepublic cimport ElementBase
  56. cdef class NewElementClass(ElementBase):
  57. def set_value(self, myval):
  58. self.set("my_attribute", myval)
  59. etree.set_element_class_lookup(
  60. etree.ElementDefaultClassLookup(element=NewElementClass))
  61. Writing external modules in C
  62. -----------------------------
  63. If you really feel like it, you can also interface with lxml.etree straight
  64. from C code. All you have to do is include the header file for the public
  65. API, import the ``lxml.etree`` module and then call the import function:
  66. .. sourcecode:: c
  67. /* My C extension */
  68. /* common includes */
  69. #include "Python.h"
  70. #include "stdio.h"
  71. #include "string.h"
  72. #include "stdarg.h"
  73. #include "libxml/xmlversion.h"
  74. #include "libxml/encoding.h"
  75. #include "libxml/hash.h"
  76. #include "libxml/tree.h"
  77. #include "libxml/xmlIO.h"
  78. #include "libxml/xmlsave.h"
  79. #include "libxml/globals.h"
  80. #include "libxml/xmlstring.h"
  81. /* lxml.etree specific includes */
  82. #include "lxml-version.h"
  83. #include "etree_defs.h"
  84. #include "etree.h"
  85. /* setup code */
  86. import_lxml__etree()
  87. Note that including ``etree.h`` does not automatically include the
  88. header files it requires. Note also that the above list of common
  89. includes may not be sufficient.