• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
NSXMLParser and initWithStream
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

NSXMLParser and initWithStream


  • Subject: NSXMLParser and initWithStream
  • From: John Drake <email@hidden>
  • Date: Sun, 27 May 2012 20:14:16 -0400

I'm trying to use the NSStream classes to parse incoming incremental XML data. The data is never a complete XML Document, but I want to receive and process it in incremental chunks based off how much ever the socket can read.

Looking at the documentation for NSXMLParser, it seems like the initWithStream: method to initialize a NSXMLParser would be the perfect solution to my problem. I can initialize the parser with a NSInputStream and then call the parse method on NSXMLParser whenever I receive data over my socket which should in turn call the NSXMLParser delegates.

However, I'm not seeing any of the delegates being called, the only method I see being called is the stream delegate stream:handleEvent:. There seems to be little to no examples of this API from Apple or other developers. I could use libxml2 directly to accomplish what I want, but I am hoping I am just using NSXMLParser incorrectly.

Here is the source for what I am trying:

ContentParser.h:

    @interface ContentParser : NSObject <NSStreamDelegate,
                                         NSXMLParserDelegate>
    {
       NSInputStream *inputStream;
       NSOutputStream *outputStream;
       NSMutableData *receivedData;
       NSXMLParser *xmlParser;
    }
    - (void)initStream;

ContentParser.m:

    @implementation ContentParser

    - (void)initStream
    {
       CFReadStreamRef readStream;
       CFWriteStreamRef writeStream;

       CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,
                                         (CFStringRef)@"<hostname>",
                                         <port>,
                                         &readStream,
                                         &writeStream);

       inputStream = (__bridge NSInputStream *)readStream;
       outputStream = (__bridge NSOutputStream *)writeStream;

       inputStream.delegate = self;
       outputStream.delegate = self;

       [inputStream  scheduleInRunLoop:[NSRunLoop currentRunLoop]
                               forMode:NSDefaultRunLoopMode];
       [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
                               forMode:NSDefaultRunLoopMode];

       [inputStream open];
       [outputStream open];

       xmlParser = [[NSXMLParser alloc] initWithStream:inputStream];
       [xmlParser setDelegate:self];
    }

    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
                                            namespaceURI:(NSString *)namespaceURI
                                           qualifiedName:(NSString *)qName
                                              attributes:(NSDictionary *)attributeDict
    {
       NSLog(@"didStartElement: %@, attributeDict: %@", elementName, attributeDict);
    }

    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
    {
       NSLog(@"foundCharacters: %@", string);
    }

    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
                                          namespaceURI:(NSString *)namespaceURI
                                         qualifiedName:(NSString *)qName
    {
       NSLog(@"didEndElement: %@", elementName);
    }

    - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
    {
       NSLog(@"Error %ld, Description: %@, Line: %ld, Column: %ld",
          [parseError code], [[parser parserError] localizedDescription],
          [parser lineNumber], [parser columnNumber]);
    }


    - (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode
    {
       switch (eventCode) {
           case NSStreamEventHasBytesAvailable:
           {
               if (stream == inputStream) {
                   NSInputStream *is = (NSInputStream *)stream;
                   if (receivedData == nil) {
                       receivedData = [[NSMutableData alloc] init];
                   }

                   uint8_t buf[1024];
                   NSInteger bytesRead = [is read:buf maxLength:1024];
                   if (bytesRead == -1) {
                      NSLog(@"Network read error");
                   } else if (bytesRead == 0) {
                      NSLog(@"No buffer received");
                   } else {
                      [receivedData appendBytes:buf length:bytesRead];
                      BOOL parserResult = [xmlParser parse];
                      if (parserResult == NO) {
                         NSLog(@"Unable to parse XML");
                      }
                   }
               }
               break;
           }
           default:
              break;
        }
    }

    @end
_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Follow-Ups:
    • RE: NSXMLParser and initWithStream
      • From: John Drake <email@hidden>
    • Re: NSXMLParser and initWithStream
      • From: Fritz Anderson <email@hidden>
  • Prev by Date: Re: Sandboxing. WTF?
  • Next by Date: Re: Sandboxing. WTF?
  • Previous by thread: Re: Sandboxing. WTF?
  • Next by thread: Re: NSXMLParser and initWithStream
  • Index(es):
    • Date
    • Thread