Re: [xml] reading data chunk by chunk



Thanks for the response.
I've updated the code, I'm using xmlReaderForIO() with an IO read function.
When some data is received on the network, my function parse() is called, with the data buffer and size. I have another class that reads data from the socket,non-blocking, and passes me just a buffer. My I/O read function is xmlRead wich feeds the data in the xmlReader. But if I call parse with an incomplete tag, I get an error like : line 1: parser error : Extra content at the end of the document. It's like the parser needs extra data to parse the string.
To test my parse function I I just call parse two times, spliting the data between the calls:
       
    xmldata = "<stream1>"
                       " <message from=\"me\">";

    parser.parse(xmldata.c_str(), xmldata.size());
    xmldata = "<body>March Hare: There’s PLENTY of room!</body>"
                       " </message>"
                       "</stream1>\n";
So the message tag closes in the second call of this function.
Here is the rest of the code:

int Parser::parse(
    const char* xmlData,
    unsigned int _size
    ) throw (InvalidXmlException) {
 
  buffer = const_cast<char*> (xmlData);
  size = _size;
  consumed = 0;

  if (firstParse){
    reader =  xmlReaderForIO(xmlRead, NULL, this, NULL, NULL, XML_PARSE_RECOVER|XML_PARSE_DTDATTR | XML_PARSE_NOENT);
    if (!reader)
      TRACEABLE_THROW(InvalidXmlException());
    firstParse = false;
  }

    int result = xmlTextReaderRead(reader);

    while (result == 1) {
      processNode(reader);
      result = xmlTextReaderRead(reader);
   }
}

int Parser::xmlRead(void *context, char* buffer, int len) {
  Parser* parser = reinterpret_cast<Parser*>(context);

  int toCopy = parser->size - parser->consumed < len ? parser->size - parser->consumed : len;
  cout << "xmlRead: " << toCopy <<"\n";
  if (toCopy == 0)
    return 0;

  std::string debug(parser->buffer + parser->consumed, toCopy);
  cout << debug <<" pushed in parser !!! \n";
  memcpy(buffer, parser->buffer + parser->consumed, toCopy);

  parser->consumed += toCopy;

  return toCopy;
}

I get this error:
Entity: line 1: parser error : Extra content at the end of the document
<stream1> <message from="me">
                                                             ^                            

Thank you for your help.


On 04/09/2011 09:32 PM, Noam Postavsky wrote:
Mircea Gliga <mgliga integrasoft ro> writes:

Hello

I am trying to parse data read from the network, so I progressively
feed the data into a reader. I'm using a xmlReaderForMemory, when I
receive the data I feed it using this function: xmlReaderNewMemory.
For pulling the data out I use xmlTextReaderRead.
Is this the correct way to do such a thing ?
No, that would make each piece of data be treated as a separate
document. You should use xmlReaderForIO() and pass an ioread function
that gets the data from the network.

http://xmlsoft.org/html/libxml-xmlreader.html#xmlReaderForIO

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature



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