348f6ad0a0a9a598e0776571d3aa9912f517b789
[platform/upstream/python-lxml.git] / doc / html / lxml-source-howto.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" />
6 <title>How to read the source of lxml</title>
7 <meta name="author" content="Stefan Behnel" />
8 <meta content="How to read and work on the source code of lxml" name="description" />
9 <meta content="lxml, XML, Cython, source code, develop, comprehend, understand" name="keywords" />
10 <link rel="stylesheet" href="style.css" type="text/css" />
11 <script type="text/javascript">
12 function trigger_menu(event) {
13     var sidemenu = document.getElementById("sidemenu");
14     var classes = sidemenu.getAttribute("class");
15     classes = (classes.indexOf(" visible") === -1) ? classes + " visible" : classes.replace(" visible", "");
16     sidemenu.setAttribute("class", classes);
17     event.preventDefault();
18     event.stopPropagation();
19 }
20 function hide_menu() {
21     var sidemenu = document.getElementById("sidemenu");
22     var classes = sidemenu.getAttribute("class");
23     if (classes.indexOf(" visible") !== -1) {
24         sidemenu.setAttribute("class", classes.replace(" visible", ""));
25     }
26 }
27 </script><meta content="width=device-width, initial-scale=1" name="viewport" /></head>
28 <body onclick="hide_menu()">
29 <div class="document" id="how-to-read-the-source-of-lxml">
30 <div class="sidemenu" id="sidemenu"><div class="menutrigger" onclick="trigger_menu(event)">Menu</div><div class="menu"><ul id="lxml-section"><li><span class="section title">lxml</span><ul class="menu foreign" id="index-menu"><li class="menu title"><a href="index.html">lxml</a><ul class="submenu"><li class="menu item"><a href="index.html#introduction">Introduction</a></li><li class="menu item"><a href="index.html#support-the-project">Support the project</a></li><li class="menu item"><a href="index.html#documentation">Documentation</a></li><li class="menu item"><a href="index.html#download">Download</a></li><li class="menu item"><a href="index.html#mailing-list">Mailing list</a></li><li class="menu item"><a href="index.html#bug-tracker">Bug tracker</a></li><li class="menu item"><a href="index.html#license">License</a></li><li class="menu item"><a href="index.html#old-versions">Old Versions</a></li><li class="menu item"><a href="index.html#legal-notice-for-donations">Legal Notice for Donations</a></li></ul></li></ul><ul class="menu foreign" id="intro-menu"><li class="menu title"><a href="intro.html">Why lxml?</a><ul class="submenu"><li class="menu item"><a href="intro.html#motto">Motto</a></li><li class="menu item"><a href="intro.html#aims">Aims</a></li></ul></li></ul><ul class="menu foreign" id="installation-menu"><li class="menu title"><a href="installation.html">Installing lxml</a><ul class="submenu"><li class="menu item"><a href="installation.html#where-to-get-it">Where to get it</a></li><li class="menu item"><a href="installation.html#requirements">Requirements</a></li><li class="menu item"><a href="installation.html#installation">Installation</a></li><li class="menu item"><a href="installation.html#building-lxml-from-dev-sources">Building lxml from dev sources</a></li><li class="menu item"><a href="installation.html#using-lxml-with-python-libxml2">Using lxml with python-libxml2</a></li><li class="menu item"><a href="installation.html#source-builds-on-ms-windows">Source builds on MS Windows</a></li><li class="menu item"><a href="installation.html#source-builds-on-macos-x">Source builds on MacOS-X</a></li></ul></li></ul><ul class="menu foreign" id="performance-menu"><li class="menu title"><a href="performance.html">Benchmarks and Speed</a><ul class="submenu"><li class="menu item"><a href="performance.html#general-notes">General notes</a></li><li class="menu item"><a href="performance.html#how-to-read-the-timings">How to read the timings</a></li><li class="menu item"><a href="performance.html#parsing-and-serialising">Parsing and Serialising</a></li><li class="menu item"><a href="performance.html#the-elementtree-api">The ElementTree API</a></li><li class="menu item"><a href="performance.html#xpath">XPath</a></li><li class="menu item"><a href="performance.html#a-longer-example">A longer example</a></li><li class="menu item"><a href="performance.html#lxml-objectify">lxml.objectify</a></li></ul></li></ul><ul class="menu foreign" id="compatibility-menu"><li class="menu title"><a href="compatibility.html">ElementTree compatibility of lxml.etree</a></li></ul><ul class="menu foreign" id="FAQ-menu"><li class="menu title"><a href="FAQ.html">lxml FAQ - Frequently Asked Questions</a><ul class="submenu"><li class="menu item"><a href="FAQ.html#general-questions">General Questions</a></li><li class="menu item"><a href="FAQ.html#installation">Installation</a></li><li class="menu item"><a href="FAQ.html#contributing">Contributing</a></li><li class="menu item"><a href="FAQ.html#bugs">Bugs</a></li><li class="menu item"><a href="FAQ.html#id1">Threading</a></li><li class="menu item"><a href="FAQ.html#parsing-and-serialisation">Parsing and Serialisation</a></li><li class="menu item"><a href="FAQ.html#xpath-and-document-traversal">XPath and Document Traversal</a></li></ul></li></ul></li></ul><ul id="Developing with lxml-section"><li><span class="section title">Developing with lxml</span><ul class="menu foreign" id="tutorial-menu"><li class="menu title"><a href="tutorial.html">The lxml.etree Tutorial</a><ul class="submenu"><li class="menu item"><a href="tutorial.html#the-element-class">The Element class</a></li><li class="menu item"><a href="tutorial.html#the-elementtree-class">The ElementTree class</a></li><li class="menu item"><a href="tutorial.html#parsing-from-strings-and-files">Parsing from strings and files</a></li><li class="menu item"><a href="tutorial.html#namespaces">Namespaces</a></li><li class="menu item"><a href="tutorial.html#the-e-factory">The E-factory</a></li><li class="menu item"><a href="tutorial.html#elementpath">ElementPath</a></li></ul></li></ul><ul class="menu foreign" id="api index-menu"><li class="menu title"><a href="api/index.html">API reference</a></li></ul><ul class="menu foreign" id="api-menu"><li class="menu title"><a href="api.html">APIs specific to lxml.etree</a><ul class="submenu"><li class="menu item"><a href="api.html#lxml-etree">lxml.etree</a></li><li class="menu item"><a href="api.html#other-element-apis">Other Element APIs</a></li><li class="menu item"><a href="api.html#trees-and-documents">Trees and Documents</a></li><li class="menu item"><a href="api.html#iteration">Iteration</a></li><li class="menu item"><a href="api.html#error-handling-on-exceptions">Error handling on exceptions</a></li><li class="menu item"><a href="api.html#error-logging">Error logging</a></li><li class="menu item"><a href="api.html#serialisation">Serialisation</a></li><li class="menu item"><a href="api.html#incremental-xml-generation">Incremental XML generation</a></li><li class="menu item"><a href="api.html#cdata">CDATA</a></li><li class="menu item"><a href="api.html#xinclude-and-elementinclude">XInclude and ElementInclude</a></li></ul></li></ul><ul class="menu foreign" id="parsing-menu"><li class="menu title"><a href="parsing.html">Parsing XML and HTML with lxml</a><ul class="submenu"><li class="menu item"><a href="parsing.html#parsers">Parsers</a></li><li class="menu item"><a href="parsing.html#the-target-parser-interface">The target parser interface</a></li><li class="menu item"><a href="parsing.html#the-feed-parser-interface">The feed parser interface</a></li><li class="menu item"><a href="parsing.html#incremental-event-parsing">Incremental event parsing</a></li><li class="menu item"><a href="parsing.html#iterparse-and-iterwalk">iterparse and iterwalk</a></li><li class="menu item"><a href="parsing.html#python-unicode-strings">Python unicode strings</a></li></ul></li></ul><ul class="menu foreign" id="validation-menu"><li class="menu title"><a href="validation.html">Validation with lxml</a><ul class="submenu"><li class="menu item"><a href="validation.html#validation-at-parse-time">Validation at parse time</a></li><li class="menu item"><a href="validation.html#id1">DTD</a></li><li class="menu item"><a href="validation.html#relaxng">RelaxNG</a></li><li class="menu item"><a href="validation.html#xmlschema">XMLSchema</a></li><li class="menu item"><a href="validation.html#id2">Schematron</a></li><li class="menu item"><a href="validation.html#id3">(Pre-ISO-Schematron)</a></li></ul></li></ul><ul class="menu foreign" id="xpathxslt-menu"><li class="menu title"><a href="xpathxslt.html">XPath and XSLT with lxml</a><ul class="submenu"><li class="menu item"><a href="xpathxslt.html#xpath">XPath</a></li><li class="menu item"><a href="xpathxslt.html#xslt">XSLT</a></li></ul></li></ul><ul class="menu foreign" id="objectify-menu"><li class="menu title"><a href="objectify.html">lxml.objectify</a><ul class="submenu"><li class="menu item"><a href="objectify.html#the-lxml-objectify-api">The lxml.objectify API</a></li><li class="menu item"><a href="objectify.html#asserting-a-schema">Asserting a Schema</a></li><li class="menu item"><a href="objectify.html#objectpath">ObjectPath</a></li><li class="menu item"><a href="objectify.html#python-data-types">Python data types</a></li><li class="menu item"><a href="objectify.html#how-data-types-are-matched">How data types are matched</a></li><li class="menu item"><a href="objectify.html#what-is-different-from-lxml-etree">What is different from lxml.etree?</a></li></ul></li></ul><ul class="menu foreign" id="lxmlhtml-menu"><li class="menu title"><a href="lxmlhtml.html">lxml.html</a><ul class="submenu"><li class="menu item"><a href="lxmlhtml.html#parsing-html">Parsing HTML</a></li><li class="menu item"><a href="lxmlhtml.html#html-element-methods">HTML Element Methods</a></li><li class="menu item"><a href="lxmlhtml.html#running-html-doctests">Running HTML doctests</a></li><li class="menu item"><a href="lxmlhtml.html#creating-html-with-the-e-factory">Creating HTML with the E-factory</a></li><li class="menu item"><a href="lxmlhtml.html#working-with-links">Working with links</a></li><li class="menu item"><a href="lxmlhtml.html#forms">Forms</a></li><li class="menu item"><a href="lxmlhtml.html#cleaning-up-html">Cleaning up HTML</a></li><li class="menu item"><a href="lxmlhtml.html#html-diff">HTML Diff</a></li><li class="menu item"><a href="lxmlhtml.html#examples">Examples</a></li></ul></li></ul><ul class="menu foreign" id="cssselect-menu"><li class="menu title"><a href="cssselect.html">lxml.cssselect</a><ul class="submenu"><li class="menu item"><a href="cssselect.html#the-cssselector-class">The CSSSelector class</a></li><li class="menu item"><a href="cssselect.html#the-cssselect-method">The cssselect method</a></li><li class="menu item"><a href="cssselect.html#supported-selectors">Supported Selectors</a></li><li class="menu item"><a href="cssselect.html#namespaces">Namespaces</a></li></ul></li></ul><ul class="menu foreign" id="elementsoup-menu"><li class="menu title"><a href="elementsoup.html">BeautifulSoup Parser</a><ul class="submenu"><li class="menu item"><a href="elementsoup.html#parsing-with-the-soupparser">Parsing with the soupparser</a></li><li class="menu item"><a href="elementsoup.html#entity-handling">Entity handling</a></li><li class="menu item"><a href="elementsoup.html#using-soupparser-as-a-fallback">Using soupparser as a fallback</a></li><li class="menu item"><a href="elementsoup.html#using-only-the-encoding-detection">Using only the encoding detection</a></li></ul></li></ul><ul class="menu foreign" id="html5parser-menu"><li class="menu title"><a href="html5parser.html">html5lib Parser</a><ul class="submenu"><li class="menu item"><a href="html5parser.html#differences-to-regular-html-parsing">Differences to regular HTML parsing</a></li><li class="menu item"><a href="html5parser.html#function-reference">Function Reference</a></li></ul></li></ul></li></ul><ul id="Extending lxml-section"><li><span class="section title">Extending lxml</span><ul class="menu foreign" id="resolvers-menu"><li class="menu title"><a href="resolvers.html">Document loading and URL resolving</a><ul class="submenu"><li class="menu item"><a href="resolvers.html#xml-catalogs">XML Catalogs</a></li><li class="menu item"><a href="resolvers.html#uri-resolvers">URI Resolvers</a></li><li class="menu item"><a href="resolvers.html#document-loading-in-context">Document loading in context</a></li><li class="menu item"><a href="resolvers.html#i-o-access-control-in-xslt">I/O access control in XSLT</a></li></ul></li></ul><ul class="menu foreign" id="extensions-menu"><li class="menu title"><a href="extensions.html">Python extensions for XPath and XSLT</a><ul class="submenu"><li class="menu item"><a href="extensions.html#xpath-extension-functions">XPath Extension functions</a></li><li class="menu item"><a href="extensions.html#xslt-extension-elements">XSLT extension elements</a></li></ul></li></ul><ul class="menu foreign" id="element classes-menu"><li class="menu title"><a href="element_classes.html">Using custom Element classes in lxml</a><ul class="submenu"><li class="menu item"><a href="element_classes.html#background-on-element-proxies">Background on Element proxies</a></li><li class="menu item"><a href="element_classes.html#element-initialization">Element initialization</a></li><li class="menu item"><a href="element_classes.html#setting-up-a-class-lookup-scheme">Setting up a class lookup scheme</a></li><li class="menu item"><a href="element_classes.html#generating-xml-with-custom-classes">Generating XML with custom classes</a></li><li class="menu item"><a href="element_classes.html#id1">Implementing namespaces</a></li></ul></li></ul><ul class="menu foreign" id="sax-menu"><li class="menu title"><a href="sax.html">Sax support</a><ul class="submenu"><li class="menu item"><a href="sax.html#building-a-tree-from-sax-events">Building a tree from SAX events</a></li><li class="menu item"><a href="sax.html#producing-sax-events-from-an-elementtree-or-element">Producing SAX events from an ElementTree or Element</a></li><li class="menu item"><a href="sax.html#interfacing-with-pulldom-minidom">Interfacing with pulldom/minidom</a></li></ul></li></ul><ul class="menu foreign" id="capi-menu"><li class="menu title"><a href="capi.html">The public C-API of lxml.etree</a><ul class="submenu"><li class="menu item"><a href="capi.html#passing-generated-trees-through-python">Passing generated trees through Python</a></li><li class="menu item"><a href="capi.html#writing-external-modules-in-cython">Writing external modules in Cython</a></li><li class="menu item"><a href="capi.html#writing-external-modules-in-c">Writing external modules in C</a></li></ul></li></ul></li></ul><ul id="Developing lxml-section"><li><span class="section title">Developing lxml</span><ul class="menu foreign" id="build-menu"><li class="menu title"><a href="build.html">How to build lxml from source</a><ul class="submenu"><li class="menu item"><a href="build.html#cython">Cython</a></li><li class="menu item"><a href="build.html#github-git-and-hg">Github, git and hg</a></li><li class="menu item"><a href="build.html#building-the-sources">Building the sources</a></li><li class="menu item"><a href="build.html#running-the-tests-and-reporting-errors">Running the tests and reporting errors</a></li><li class="menu item"><a href="build.html#building-an-egg-or-wheel">Building an egg or wheel</a></li><li class="menu item"><a href="build.html#building-lxml-on-macos-x">Building lxml on MacOS-X</a></li><li class="menu item"><a href="build.html#static-linking-on-windows">Static linking on Windows</a></li><li class="menu item"><a href="build.html#building-debian-packages-from-svn-sources">Building Debian packages from SVN sources</a></li></ul></li></ul><ul class="menu current" id="lxml source howto-menu"><li class="menu title"><a href="lxml-source-howto.html">How to read the source of lxml</a><ul class="submenu"><li class="menu item"><a href="lxml-source-howto.html#what-is-cython">What is Cython?</a></li><li class="menu item"><a href="lxml-source-howto.html#where-to-start">Where to start?</a></li><li class="menu item"><a href="lxml-source-howto.html#lxml-etree">lxml.etree</a></li><li class="menu item"><a href="lxml-source-howto.html#python-modules">Python modules</a></li><li class="menu item"><a href="lxml-source-howto.html#lxml-objectify">lxml.objectify</a></li><li class="menu item"><a href="lxml-source-howto.html#lxml-html">lxml.html</a></li></ul></li></ul><ul class="menu foreign" id="changes 4 4 3-menu"><li class="menu title"><a href="changes-4.4.3.html">Release Changelog</a></li></ul><ul class="menu foreign" id="credits-menu"><li class="menu title"><a href="credits.html">Credits</a><ul class="submenu"><li class="menu item"><a href="credits.html#main-contributors">Main contributors</a></li><li class="menu item"><a href="credits.html#special-thanks-goes-to">Special thanks goes to:</a></li></ul></li></ul></li><li><a href="/sitemap.html">Sitemap</a></li></ul></div></div><h1 class="title">How to read the source of lxml</h1>
31 <table class="docinfo" frame="void" rules="none">
32 <col class="docinfo-name" />
33 <col class="docinfo-content" />
34 <tbody valign="top">
35 <tr><th class="docinfo-name">Author:</th>
36 <td>Stefan Behnel</td></tr>
37 </tbody>
38 </table>
39 <p>This document describes how to read the source code of <a class="reference external" href="http://lxml.de/">lxml</a> and how
40 to start working on it.  You might also be interested in the companion
41 document that describes <a class="reference external" href="build.html">how to build lxml from sources</a>.</p>
42 <div class="contents topic" id="contents">
43 <p class="topic-title first">Contents</p>
44 <ul class="simple">
45 <li><a class="reference internal" href="#what-is-cython" id="id1">What is Cython?</a></li>
46 <li><a class="reference internal" href="#where-to-start" id="id2">Where to start?</a><ul>
47 <li><a class="reference internal" href="#concepts" id="id3">Concepts</a></li>
48 <li><a class="reference internal" href="#the-documentation" id="id4">The documentation</a></li>
49 </ul>
50 </li>
51 <li><a class="reference internal" href="#lxml-etree" id="id5">lxml.etree</a></li>
52 <li><a class="reference internal" href="#python-modules" id="id6">Python modules</a></li>
53 <li><a class="reference internal" href="#lxml-objectify" id="id7">lxml.objectify</a></li>
54 <li><a class="reference internal" href="#lxml-html" id="id8">lxml.html</a></li>
55 </ul>
56 </div>
57 <div class="section" id="what-is-cython">
58 <h1>What is Cython?</h1>
59 <p><a class="reference external" href="http://cython.org/">Cython</a> is the language that lxml is written in.  It is a very
60 Python-like language that was specifically designed for writing Python
61 extension modules.</p>
62 <p>The reason why Cython (or actually its predecessor <a class="reference external" href="http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/">Pyrex</a> at the time)
63 was chosen as an implementation language for lxml, is that it makes it
64 very easy to interface with both the Python world and external C code.
65 Cython generates all the necessary glue code for the Python API,
66 including Python types, calling conventions and reference counting.
67 On the other side of the table, calling into C code is not more than
68 declaring the signature of the function and maybe some variables as
69 being C types, pointers or structs, and then calling it.  The rest of
70 the code is just plain Python code.</p>
71 <p>The Cython language is so close to Python that the Cython compiler can
72 actually compile many, many Python programs to C without major
73 modifications.  But the real speed gains of a C compilation come from
74 type annotations that were added to the language and that allow Cython
75 to generate very efficient C code.</p>
76 <p>Even if you are not familiar with Cython, you should keep in mind that
77 a slow implementation of a feature is better than none.  So, if you
78 want to contribute and have an idea what code you want to write, feel
79 free to start with a pure Python implementation.  Chances are, if you
80 get the change officially accepted and integrated, others will take
81 the time to optimise it so that it runs fast in Cython.</p>
82 </div>
83 <div class="section" id="where-to-start">
84 <h1>Where to start?</h1>
85 <p>First of all, read <a class="reference external" href="build.html">how to build lxml from sources</a> to learn how to
86 retrieve the source code from the GitHub repository and how to
87 build it.  The source code lives in the subdirectory <tt class="docutils literal">src</tt> of the
88 checkout.</p>
89 <p>The main extension modules in lxml are <tt class="docutils literal">lxml.etree</tt> and
90 <tt class="docutils literal">lxml.objectify</tt>.  All main modules have the file extension
91 <tt class="docutils literal">.pyx</tt>, which shows the descendence from Pyrex.  As usual in Python,
92 the main files start with a short description and a couple of imports.
93 Cython distinguishes between the run-time <tt class="docutils literal">import</tt> statement (as
94 known from Python) and the compile-time <tt class="docutils literal">cimport</tt> statement, which
95 imports C declarations, either from external libraries or from other
96 Cython modules.</p>
97 <div class="section" id="concepts">
98 <h2>Concepts</h2>
99 <p>lxml's tree API is based on proxy objects.  That means, every Element
100 object (or rather <tt class="docutils literal">_Element</tt> object) is a proxy for a libxml2 node
101 structure.  The class declaration is (mainly):</p>
102 <pre class="literal-block">
103 cdef class _Element:
104     cdef _Document _doc
105     cdef xmlNode* _c_node
106 </pre>
107 <p>It is a naming convention that C variables and C level class members
108 that are passed into libxml2 start with a prefixed <tt class="docutils literal">c_</tt> (commonly
109 libxml2 struct pointers), and that C level class members are prefixed
110 with an underscore.  So you will often see names like <tt class="docutils literal">c_doc</tt> for an
111 <tt class="docutils literal">xmlDoc*</tt> variable (or <tt class="docutils literal">c_node</tt> for an <tt class="docutils literal">xmlNode*</tt>), or the above
112 <tt class="docutils literal">_c_node</tt> for a class member that points to an <tt class="docutils literal">xmlNode</tt> struct
113 (or <tt class="docutils literal">_c_doc</tt> for an <tt class="docutils literal">xmlDoc*</tt>).</p>
114 <p>It is important to know that every proxy in lxml has a factory
115 function that properly sets up C level members.  Proxy objects must
116 <em>never</em> be instantiated outside of that factory.  For example, to
117 instantiate an _Element object or its subclasses, you must always call
118 its factory function:</p>
119 <pre class="literal-block">
120 cdef xmlNode* c_node
121 cdef _Document doc
122 cdef _Element element
123 ...
124 element = _elementFactory(doc, c_node)
125 </pre>
126 <p>A good place to see how this factory is used are the Element methods
127 <tt class="docutils literal">getparent()</tt>, <tt class="docutils literal">getnext()</tt> and <tt class="docutils literal">getprevious()</tt>.</p>
128 </div>
129 <div class="section" id="the-documentation">
130 <h2>The documentation</h2>
131 <p>An important part of lxml is the documentation that lives in the
132 <tt class="docutils literal">doc</tt> directory.  It describes a large part of the API and comprises
133 a lot of example code in the form of doctests.</p>
134 <p>The documentation is written in the <a class="reference external" href="http://docutils.sourceforge.net/rst.html">ReStructured Text</a> format, a
135 very powerful text markup language that looks almost like plain text.
136 It is part of the <a class="reference external" href="http://docutils.sourceforge.net/">docutils</a> package.</p>
137 <p>The project web site of <a class="reference external" href="http://lxml.de/">lxml</a> is completely generated from these text
138 documents.  Even the side menu is just collected from the table of
139 contents that the ReST processor writes into each HTML page.
140 Obviously, we use lxml for this.</p>
141 <p>The easiest way to generate the HTML pages is by calling:</p>
142 <pre class="literal-block">
143 make html
144 </pre>
145 <p>This will call the script <tt class="docutils literal">doc/mkhtml.py</tt> to run the ReST processor
146 on the files.  After generating an HTML page the script parses it back
147 in to build the side menu, and injects the complete menu into each
148 page at the very end.</p>
149 <p>Running the <tt class="docutils literal">make</tt> command will also generate the API documentation
150 if you have <a class="reference external" href="http://epydoc.sourceforge.net/">epydoc</a> installed.  The epydoc package will import and
151 introspect the extension modules and also introspect and parse the
152 Python modules of lxml.  The aggregated information will then be
153 written out into an HTML documentation site.</p>
154 </div>
155 </div>
156 <div class="section" id="lxml-etree">
157 <h1>lxml.etree</h1>
158 <p>The main module, <tt class="docutils literal">lxml.etree</tt>, is in the file <a class="reference external" href="https://github.com/lxml/lxml/blob/master/src/lxml/etree.pyx">lxml.etree.pyx</a>.  It
159 implements the main functions and types of the ElementTree API, as
160 well as all the factory functions for proxies.  It is the best place
161 to start if you want to find out how a specific feature is
162 implemented.</p>
163 <p>At the very end of the file, it contains a series of <tt class="docutils literal">include</tt>
164 statements that merge the rest of the implementation into the
165 generated C code.  Yes, you read right: no importing, no source file
166 namespacing, just plain good old include and a huge C code result of
167 more than 100,000 lines that we throw right into the C compiler.</p>
168 <p>The main include files are:</p>
169 <dl class="docutils">
170 <dt>apihelpers.pxi</dt>
171 <dd>Private C helper functions.  Except for the factory functions,
172 most of the little functions that are used all over the place are
173 defined here.  This includes things like reading out the text
174 content of a libxml2 tree node, checking input from the API level,
175 creating a new Element node or handling attribute values.  If you
176 want to work on the lxml code, you should keep these functions in
177 the back of your head, as they will definitely make your life
178 easier.</dd>
179 <dt>classlookup.pxi</dt>
180 <dd>Element class lookup mechanisms.  The main API and engines for
181 those who want to define custom Element classes and inject them
182 into lxml.</dd>
183 <dt>docloader.pxi</dt>
184 <dd>Support for custom document loaders.  Base class and registry for
185 custom document resolvers.</dd>
186 <dt>extensions.pxi</dt>
187 <dd>Infrastructure for extension functions in XPath/XSLT, including
188 XPath value conversion and function registration.</dd>
189 <dt>iterparse.pxi</dt>
190 <dd>Incremental XML parsing.  An iterator class that builds iterparse
191 events while parsing.</dd>
192 <dt>nsclasses.pxi</dt>
193 <dd>Namespace implementation and registry.  The registry and engine
194 for Element classes that use the ElementNamespaceClassLookup
195 scheme.</dd>
196 <dt>parser.pxi</dt>
197 <dd>Parsers for XML and HTML.  This is the main parser engine.  It's
198 the reason why you can parse a document from various sources in
199 two lines of Python code.  It's definitely not the right place to
200 start reading lxml's source code.</dd>
201 <dt>parsertarget.pxi</dt>
202 <dd>An ElementTree compatible parser target implementation based on
203 the SAX2 interface of libxml2.</dd>
204 <dt>proxy.pxi</dt>
205 <dd>Very low-level functions for memory allocation/deallocation
206 and Element proxy handling.  Ignoring this for the beginning
207 will safe your head from exploding.</dd>
208 <dt>public-api.pxi</dt>
209 <dd>The set of C functions that are exported to other extension
210 modules at the C level.  For example, <tt class="docutils literal">lxml.objectify</tt> makes use
211 of these.  See the <cite>C-level API</cite> documentation.</dd>
212 <dt>readonlytree.pxi</dt>
213 <dd>A separate read-only implementation of the Element API.  This is
214 used in places where non-intrusive access to a tree is required,
215 such as the <tt class="docutils literal">PythonElementClassLookup</tt> or XSLT extension
216 elements.</dd>
217 <dt>saxparser.pxi</dt>
218 <dd>SAX-like parser interfaces as known from ElementTree's TreeBuilder.</dd>
219 <dt>serializer.pxi</dt>
220 <dd>XML output functions.  Basically everything that creates byte
221 sequences from XML trees.</dd>
222 <dt>xinclude.pxi</dt>
223 <dd>XInclude support.</dd>
224 <dt>xmlerror.pxi</dt>
225 <dd><p class="first">Error log handling.  All error messages that libxml2 generates
226 internally walk through the code in this file to end up in lxml's
227 Python level error logs.</p>
228 <p class="last">At the end of the file, you will find a long list of named error
229 codes.  It is generated from the libxml2 HTML documentation (using
230 lxml, of course).  See the script <tt class="docutils literal"><span class="pre">update-error-constants.py</span></tt>
231 for this.</p>
232 </dd>
233 <dt>xmlid.pxi</dt>
234 <dd>XMLID and IDDict, a dictionary-like way to find Elements by their
235 XML-ID attribute.</dd>
236 <dt>xpath.pxi</dt>
237 <dd>XPath evaluators.</dd>
238 <dt>xslt.pxi</dt>
239 <dd>XSL transformations, including the <tt class="docutils literal">XSLT</tt> class, document lookup
240 handling and access control.</dd>
241 </dl>
242 <p>The different schema languages (DTD, RelaxNG, XML Schema and
243 Schematron) are implemented in the following include files:</p>
244 <ul class="simple">
245 <li>dtd.pxi</li>
246 <li>relaxng.pxi</li>
247 <li>schematron.pxi</li>
248 <li>xmlschema.pxi</li>
249 </ul>
250 </div>
251 <div class="section" id="python-modules">
252 <h1>Python modules</h1>
253 <p>The <tt class="docutils literal">lxml</tt> package also contains a number of pure Python modules:</p>
254 <dl class="docutils">
255 <dt>builder.py</dt>
256 <dd>The E-factory and the ElementBuilder class.  These provide a
257 simple interface to XML tree generation.</dd>
258 <dt>cssselect.py</dt>
259 <dd>A CSS selector implementation based on XPath.  The main class is
260 called <tt class="docutils literal">CSSSelector</tt>.</dd>
261 <dt>doctestcompare.py</dt>
262 <dd>A relaxed comparison scheme for XML/HTML markup in doctest.</dd>
263 <dt>ElementInclude.py</dt>
264 <dd>XInclude-like document inclusion, compatible with ElementTree.</dd>
265 <dt>_elementpath.py</dt>
266 <dd>XPath-like path language, compatible with ElementTree.</dd>
267 <dt>sax.py</dt>
268 <dd>SAX2 compatible interfaces to copy lxml trees from/to SAX compatible
269 tools.</dd>
270 <dt>usedoctest.py</dt>
271 <dd>Wrapper module for <tt class="docutils literal">doctestcompare.py</tt> that simplifies its usage
272 from inside a doctest.</dd>
273 </dl>
274 </div>
275 <div class="section" id="lxml-objectify">
276 <h1>lxml.objectify</h1>
277 <p>A Cython implemented extension module that uses the public C-API of
278 lxml.etree.  It provides a Python object-like interface to XML trees.
279 The implementation resides in the file <a class="reference external" href="https://github.com/lxml/lxml/blob/master/src/lxml/objectify.pyx">lxml.objectify.pyx</a>.</p>
280 </div>
281 <div class="section" id="lxml-html">
282 <h1>lxml.html</h1>
283 <p>A specialised toolkit for HTML handling, based on lxml.etree.  This is
284 implemented in pure Python.</p>
285 </div>
286 </div>
287 <div class="footer">
288 <hr class="footer" />
289 Generated on: 2020-01-29.
290
291 </div>
292 </body>
293 </html>