<pre>2009-07-20,"Stefan Behnel" &lt;stefan_ml@behnel.de&gt; :
&gt;
&gt;qhlonline wrote:
&gt;&gt; I have tried to alter the libxml2 source to add a callback telling the 
&gt;&gt; current position when an element parsed.
&gt;
&gt;Note that something that requires patching libxml2 will not make it into an
&gt;lxml release.
&gt;
&gt;As you noted before, the parser context already provides this information
&gt;at any time, not only when parsing elements. So adding a callback for it is
&gt;not a sensible approach.
&gt;
&gt;I'm not even sure what this position means exactly. Is it (1) the byte
&gt;position in the original (undecoded) data stream, (2) the byte position in
&gt;the UTF-8 encoded parse stream, or (3) the character position in the XML
&gt;stream?
&gt;
&gt;According to the libxml2 docs:
&gt;
&gt;        long nbChars : number of xmlChar processed
&gt;
&gt;This sounds like it's the second information. That would not be useful and
&gt;shouldn't get exposed in lxml's API as it's rather error prone to rely on
&gt;it: works for ASCII and UTF-8, obviously, may work for some other encodings
&gt;depending on the data, but fails for most other streams. OTOH, the first
&gt;and the third information /might/ be of interest, depending on your use
&gt;case, but are not easily recovered from the information that the parser
&gt;provides.
&gt;
&gt;
&gt;&gt; I have nerver compile cython source before. Can any body give me some
&gt;&gt; suggestion?
&gt;
&gt;If you just change lxml's sources, running setup.py will build it just as
&gt;before. All you need to do is install Cython 0.11 or later.
&gt;
&gt;http://codespeak.net/lxml/build.html
&gt;
&gt;Stefan
<br>Thanks for Stefan's suggestion,I have finished the alternation of libxml2 and lxml code to add callback which can fetch the current position of HTML tag when parsing with Target parser.<br>   Firstly, I have changed the libxml2 library, There are three files I shoud deal with:<br>&nbsp;<font color="#800000">"parser.h"</font>, where all callbacks are declared, I have added my event declaration here:<br>typedef void (*getCurrentPosFunc) (void *ctx,<br>                                const xmlChar *tagname,<br>                                const unsigned long current_position );<br> Then add this event to Handler structure defination, in struct _xmlSAXHandler and struct _xmlSAXHandlerV1, add the statement as:<br>   getCurrentPosFunc getCurrentPos;<br>Note, In struct _xmlSAXHandlerV1, the event shoud also be added in. I have thought of only the structure _xmlSAXHandler had been used since it was SAX2 and I didn't add anything to _xmlSAXHandlerV1, as a result, the changed lxml library will always report "Segmentation fault" error, Until I add my event to the "V1" structure. <br> Then the file "<font color="#800000">SAX2.c</font>", There are three changes at all. The former two changes are adding event handler to parser init functions: in function xmlSAX2InitHtmlDefaultSAXHandler and function xmlSAXVersion, add statement as follow:<br>   hdlr-&gt;getCurrentPos= xmlGetCurrentPosition;<br>Then the third change, I have write the xmlGetCurrentPosition function myself, It is simplely a statement with ";", doing nothing at all.I add this function to avoid my self defined event affecting libxml2's DOM parsers.<br>   The third file to deal with is "<font color="#800000">HTMLparser.c</font>", in the function htmlParseStartTag, add my event handler here to get the position:<br>   ctxt-&gt;sax-&gt;getCurrentPos(ctxt-&gt;userData, name, ctxt-&gt;nbChars);<br>The third parameter is the current position. Althouth I have changed the normal HTML parsing function, It will not affect the DOM parser, because I have defined an event handler doing nothing in the former file.<br>   Recompile the libxml2 library and install it, Now libxml2 support getting SAX parser's position.<br>   Then some source of lxml files should also be altered: <br>   In "<font color="#800000">xmlparser.pxd</font>", adding getCurrentPos event declaration according to that in "<font color="#800000">parser.h</font>", add an event to xmlSAXHandler in this file too.<br>   In "<font color="#800000">saxparser.pxi</font>", Add new event in enum _SaxParserEvents:<br>   SAX_EVENT_POSITION = 64 <br>   Then add source code to class _SaxParserTarget and class _SaxParserContext according to context events, It is not very hard. At last in this source file, add a function to convert  C event handler to Python event handler. Because my event handler parameters are integers and string, They are supported by Cython of automatic converting, So it is not hard either.<br>  To support lxml target parser, I have modified the third file "<font color="#800000">parsertarget.pxi</font>". In this file , In defination of class _PythonSaxParserTarget, adding a member as follow:<br>    cdef object _target_position<br>In this class I have changed the __init__ function to add a new event handler called "position" to all target parsers. and then add a handler as member function in this class, with the statement like : <br>       return self._target_position(tag,current_position)<br>At last, recompile the lxml library and install it:<br>      python setup.py build<br>      python setup.py install<br>  Now the new lxml library support a new event handler called "position", It takes two parameters:a tagname and its position in the HTML file being parsed.<br>    This method is usefull for my task of getting a target parser support parsing position. But I don't know whether my change will take in new bugs, and, as Stefan has said, if lxml library or libxml2 library upgrades, all changes should be redo. So it is not suggested if no same requirement.<br>   &nbsp;And if somebody has deep understanding about libxml2 library,I wan't to ask a question. During my changing the libxml2 source, When I did not add my self-defined event handler to _xmlSAXHandlerV1 structure and function xmlSAXVersion, libxml2 will still support self-defined SAX parser, But it didn't support DOM parsers. It will report "Segmentation fault". GDB tracking found that in function  xmlNewDocPI of "<font color="#800000">tree.c</font>" had called the xmlStrdup function which raised the "Segmentation fault". Why? and lxml's target parser will also raise this signal, Is there any relationship?<br>   &nbsp;Thanks.<br> Best regards!<br><br></pre><br><!-- footer --><br><span title="neteasefooter"/><hr/>
<a href="http://www.yeah.net/?from=footer">网易YEAH.NET免费邮箱:您的终身免费邮箱</a>
</span>