Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9245055
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 18, 20262026-06-18T09:10:47+00:00 2026-06-18T09:10:47+00:00

Update: When using NSXMLParser class method initWithContentsOfURL , rather than parsing as the XML

  • 0

Update:

When using NSXMLParser class method initWithContentsOfURL, rather than parsing as the XML feed is downloaded, it appears to try to load the entire XML file into memory, and only then initiate the parsing process. This is problematic if the XML feed is large (using an excessive amount of RAM, inherently inefficient because rather than parsing in parallel with the download, it only starts the parsing once the download is done, etc.).

Has anyone discovered how to parse as the feed is being streamed to the device using NSXMLParser? Yes, you can use LibXML2 (as discussed below), but it seems like it should be possible to do it with NSXMLParser. But it’s eluding me.

Original question:

I was wrestling with using NSXMLParser to read XML from a web stream. If you use initWithContentsOfURL, while the interface may lead one to infer that it would stream the XML from the web, it doesn’t seem to to do so, but rather appears to attempt to load the entire XML file first before any parsing taking place. For modest sized XML files that’s fine, but for really large ones, that’s problematic.

I have seen discussions of using NSXMLParser in conjunction with initWithStream with some customized NSInputStream that is streaming from the web. For example, there have been answers to this that suggest using something like the CFStreamCreateBoundPair referred to in the following Cocoa Builder post and the discussion of Setting Up Socket Streams in the Apple Stream Programming Guide, but I have not gotten it to work. I even tried writing my own subclassed NSInputStream that used a NSURLConnection (which is, itself, pretty good at streaming) but I wasn’t able to get it to work in conjunction with NSXMLParser.

In the end, I decided to use LibXML2 rather than NSXMLParser, as demonstrated in the Apple XMLPerformance sample, but I was wondering if anyone had any luck getting streaming from a web source working with NSXMLParser. I’ve seen plenty of “theoretically you could do x” sort of answers, suggesting everything from CFStreamCreateBoundPair to grabbing the HTTPBodyStream from NSURLRequest, but I’ve yet to come across a working demonstration of streaming with NSXMLParser.

The Ray Wenderlich article How To Choose The Best XML Parser for Your iPhone Project seems to confirm that NSXMLParser is not well suited for large XML files, but with all of the posts about possible NSXMLParser-based work-arounds for streaming really large XML files, I’m surprised I have yet to find a working demonstration of this. Does anyone know of a functioning NSXMLParser implementation that streams from the web? Clearly, I can just stick with LibXML2 or some other equivalent XML parser, but the notion of streaming with NSXMLParser seems tantilizingly close.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-18T09:10:48+00:00Added an answer on June 18, 2026 at 9:10 am

    -[NSXMLParser initWithStream:] is the only interface to NSXMLParser that currently performs a streaming parse of the data. Hooking it up to an asynchronous NSURLConnection that’s providing data incrementally is unwieldy because NSXMLParser takes a blocking, “pull”-based approach to reading from the NSInputStream. That is, -[NSXMLParser parse] does something like the following when dealing with an NSInputStream:

    while (1) {
        NSInteger length = [stream read:buffer maxLength:maxLength];
        if (!length)
            break;
    
        // Parse data …
    }
    

    In order to incrementally provide data to this parser a custom NSInputStream subclass is needed that funnels data received by the NSURLConnectionDelegate calls on a background queue or runloop over to the -read:maxLength: call that NSXMLParser is waiting on.

    A proof-of-concept implementation follows:

    #include <Foundation/Foundation.h>
    
    @interface ReceivedDataStream : NSInputStream <NSURLConnectionDelegate>
    @property (retain) NSURLConnection *connection;
    @property (retain) NSMutableArray *bufferedData;
    @property (assign, getter=isFinished) BOOL finished;
    @property (retain) dispatch_semaphore_t semaphore;
    @end
    
    @implementation ReceivedDataStream
    
    - (id)initWithContentsOfURL:(NSURL *)url
    {
        if (!(self = [super init]))
            return nil;
    
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        self.connection = [[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO] autorelease];
        self.connection.delegateQueue = [[[NSOperationQueue alloc] init] autorelease];
        self.bufferedData = [NSMutableArray array];
        self.semaphore = dispatch_semaphore_create(0);
    
        return self;
    }
    
    - (void)dealloc
    {
        self.connection = nil;
        self.bufferedData = nil;
        self.semaphore = nil;
    
        [super dealloc];
    }
    
    - (BOOL)hasBufferedData
    {
        @synchronized (self) { return self.bufferedData.count > 0; }
    }
    
    #pragma mark - NSInputStream overrides
    
    - (void)open
    {
        NSLog(@"open");
        [self.connection start];
    }
    
    - (void)close
    {
        NSLog(@"close");
        [self.connection cancel];
    }
    
    - (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)maxLength
    {
        NSLog(@"read:%p maxLength:%ld", buffer, maxLength);
        if (self.isFinished && !self.hasBufferedData)
            return 0;
    
        if (!self.hasBufferedData)
            dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
    
        NSAssert(self.isFinished || self.hasBufferedData, @"Was woken without new information");
    
        if (self.isFinished && !self.hasBufferedData)
            return 0;
    
        NSData *data = nil;
        @synchronized (self) {
            data = [[self.bufferedData[0] retain] autorelease];
            [self.bufferedData removeObjectAtIndex:0];
            if (data.length > maxLength) {
                NSData *remainingData = [NSData dataWithBytes:data.bytes + maxLength length:data.length - maxLength];
                [self.bufferedData insertObject:remainingData atIndex:0];
            }
        }
    
        NSUInteger copiedLength = MIN([data length], maxLength);
        memcpy(buffer, [data bytes], copiedLength);
        return copiedLength;
    }
    
    
    #pragma mark - NSURLConnetionDelegate methods
    
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
    {
        NSLog(@"connection:%@ didReceiveData:…", connection);
        @synchronized (self) {
            [self.bufferedData addObject:data];
        }
        dispatch_semaphore_signal(self.semaphore);
    }
    
    - (void)connectionDidFinishLoading:(NSURLConnection *)connection
    {
        NSLog(@"connectionDidFinishLoading:%@", connection);
        self.finished = YES;
        dispatch_semaphore_signal(self.semaphore);
    }
    
    @end
    
    @interface ParserDelegate : NSObject <NSXMLParserDelegate>
    @end
    
    @implementation ParserDelegate
    
    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
    {
        NSLog(@"parser:%@ didStartElement:%@ namespaceURI:%@ qualifiedName:%@ attributes:%@", parser, elementName, namespaceURI, qualifiedName, attributeDict);
    }
    
    - (void)parserDidEndDocument:(NSXMLParser *)parser
    {
        NSLog(@"parserDidEndDocument:%@", parser);
        CFRunLoopStop(CFRunLoopGetCurrent());
    }
    
    @end
    
    
    int main(int argc, char **argv)
    {
        @autoreleasepool {
    
            NSURL *url = [NSURL URLWithString:@"http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml"];
            ReceivedDataStream *stream = [[ReceivedDataStream alloc] initWithContentsOfURL:url];
            NSXMLParser *parser = [[NSXMLParser alloc] initWithStream:stream];
            parser.delegate = [[[ParserDelegate alloc] init] autorelease];
    
            [parser performSelector:@selector(parse) withObject:nil afterDelay:0.0];
    
            CFRunLoopRun();
    
        }
        return 0;
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Update: Using the following gets back an XML response. Used NSXMLParser to check for
I'm actually using the NSXMLParser class for parse an XML file hosted on a
I need to insert, delete and update data using a xml file. I have
How do I get NHibernate to save or update using column other than the
How do I properly setup the callback method for a status update using the
Is running an update using a WHERE pkey IN () is more optimal than
I'm trying to request a single location update using the new LocationManager.requestSingleUpdate() method, but
I am extracting data from web service(xml file) using NSXmlParser.How can I write to
I am using NSXMLParser to parse some xml data. I am using some delegate
I'm using NSXMLParser to parse an xml from a url (my code is almost

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.