[xml] Need example / help for using SAX parsing on IO stream (socket)


I've been searching for documentation and / or code examples for using
the SAX parser in libxml2 to parse an input stream (XML messages being
received over a socket). I have played around a lot, but need some
guidance on how to use the IO methods and SAX....

Here are the goals I'm trying to acheive with this code:

1. parse an input stream of messages (from a socket connection) 

2. parse "on the fly" (i.e. don't require that the entire message has
been collected before parsing). I assume this implies using SAX and I/O
stream methods. 

3. keep memory requirements low by not creating a tree (i.e. use SAX). 

4. account for the retrieval of a message requiring multiple reads from
the socket (i.e. the message length is larger than the socket's buffer).

My guess as to how to go about this is to use the following methods, but
I need some verification that I'm using the right ones, and an example
of how to piece it all together: For now I just want to get the basics
working, and have a print out when the start of a message ("<rpc
message-id="123">") or the end of a message ("</rpc>") is detected, and
I'll build from there...

xmlSAXHandler SAXHandlerStruct = {
    NULL, //internalSubset,
    NULL, //isStandalone,
    NULL, //hasInternalSubset,
    NULL, //hasExternalSubset,
    NULL, //resolveEntity,
    NULL, //getEntity,
    NULL, //entityDecl,
    NULL, //notationDecl,
    NULL, //attributeDecl,
    NULL, //elementDecl,
    NULL, //unparsedEntityDecl,
    NULL, //setDocumentLocator,
    detectedStartTag, //startDocument,
    detectedEndTag, //endDocument
    NULL, //startElement
    NULL, // endElement,
    NULL, //reference,
    NULL, // characters,
    NULL, //ignorableWhitespace,
    NULL, //processingInstruction,
    NULL, //comment,
    NULL, //warning,
    NULL, //error,
    NULL, //fatalError,
    NULL, //getParameterEntity,
    NULL //cdataBlock

xmlSAXHandlerPtr SAXHandler = &SAXHandlerStruct;

//  detectedStartTag (void * ctx, 
//                               const xmlChar * fullname, 
//                               const xmlChar ** atts)
//      -called when the SAX parser detects the start tag.
void detectedStartTag (void * ctx  ATTRIBUTE_UNUSED)
        printf("EXECUTING detectedStartTag() method!! \n");

//  detectedEndTag (void * ctx, 
//                               const xmlChar * fullname, 
//                               const xmlChar ** atts)
//      -called when the SAX parser detects the end tag.
void detectedEndTag (void * ctx ATTRIBUTE_UNUSED)
        printf("EXECUTING detectedEndTag() method!! \n");

xmlInputReadCallback mmiReadSocket (void * context,
                                    char * buffer,
                                    int len)
      len = read(newSocketHandle, buffer, len);
      return len;


int main()
    xmlParserCtxtPtr ctxt;
    //int numchars;

    //...code to setup socket, listen, accept, etc.

    printf ("Before xmlCreateIOParserCtxt()\n");

    //xmlSAX2InitDefaultSAXHandler(xmlSAXHandler * hdlr, int warning);
    // Is this needed?

        Function: xmlCreateIOParserCtxt

        xmlParserCtxtPtr        xmlCreateIOParserCtxt
(xmlSAXHandlerPtr sax, 
                                                 void * user_data, 
                                                 void * ioctx, 
                                                 xmlCharEncoding enc)

        Create a parser context for using the XML parser with an
existing I/O stream
        sax: a SAX handler
        user_data: The user data returned on SAX callbacks
        ioread: an I/O read function
        ioclose: an I/O close function
        ioctx: an I/O handler
        enc: the charset encoding if known
        Returns: the new parser context or NULL

    ctxt = xmlCreateIOParserCtxt(SAXHandler,
                                        mmiReadSocket, // I get a
compile error.
                                        NULL, // Do I need this?
                                        NULL, // Do I need this?
    printf ("After xmlCreateIOParserCtxt()\n");

        // Am I missing code here? Do I need to explicitly read from the
socket? or will
        // having the ctxt setup and the mmiReadSocket() method
registered be enough?
        // I'm kinda lost as to what all I need....



} // end of main

Chris Hesterman 

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]