1

我正在尝试使用 NSXMLParser 构建一个不错的小类来满足我的需要。我以这种方式调用该类:ViewController.m:

[IDAN_XML_Parser setXmlString:soapMsg];
[IDAN_XML_Parser setStringToFind:@"userID"];
[IDAN_XML_Parser setHeader:kAPP_PASSWORD andHeaderValue:kAPP_HEADER];
[IDAN_XML_Parser setSetupXml:kWEB_SERVICE_URL];
[IDAN_XML_Parser prepareParsingAndGetResponse];

NSString *answer = [IDAN_XML_Parser getResponse];
NSLog(@"Response: %@", answer);

我的课是这样的:

.h 文件:

#import <Foundation/Foundation.h>

@interface IDAN_XML_Parser : NSObject <NSXMLParserDelegate, NSURLConnectionDelegate>



+ (void)setXmlString:(NSString *)theXML;
+ (void)setStringToFind:(NSString *)stringToFind;
+ (void)setSetupXml:(NSString *)webServicesURL;
+ (void)setHeader:(NSString *)headerKey andHeaderValue:(NSString *)headerValue;
+ (BOOL)prepareParsingAndGetResponse;
- (NSInteger)startParsing;
+ (BOOL)isParsingOK;
+ (IDAN_XML_Parser *)sharedXML;
+ (NSString *)getXMLString;
+ (NSString *)getResponse;




@end

.m 文件

#import "IDAN_XML_Parser.h"



@implementation IDAN_XML_Parser


NSString *matchingElement;
NSString *xmlString;
NSMutableData *webData;
NSURLConnection *conn;
NSString *soapHeader_key;
NSString *soapHeader_value;
NSURL *url;
BOOL isHeader = NO;
NSInteger didGetError = 0;
BOOL elementFound;
NSMutableString *soapResults;
NSString *returnedString;
NSXMLParser *xmlParser;
NSString *exceptionReason;
NSString *resultXML;


#pragma mark - Setup Parsing

+ (IDAN_XML_Parser *)sharedXML
{
    static IDAN_XML_Parser *theParser;
    @synchronized(self) {
        if (!theParser)
            theParser = [[self alloc] init];
    }
    return theParser;
}

+ (void)setXmlString:(NSString *)theXML
{
    xmlString = theXML;
    NSLog(@"\n\nXML TO SEND: %@", xmlString);
}

+ (void)setStringToFind:(NSString *)stringToFind
{
    matchingElement = stringToFind;
}

+ (void)setHeader:(NSString *)headerKey andHeaderValue:(NSString *)headerValue
{
    isHeader = YES;
    soapHeader_key = headerKey;
    soapHeader_value = headerValue;
}

+ (void)setSetupXml:(NSString *)webServicesURL
{
    url = [NSURL URLWithString:webServicesURL];
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
    NSString *msgLength = [NSString stringWithFormat:@"%d", [xmlString length]];
    [req addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [req addValue:msgLength forHTTPHeaderField:@"Content-Length"];
    [req setHTTPMethod:@"POST"];
    [req setHTTPBody: [xmlString dataUsingEncoding:NSUTF8StringEncoding]];

    if (isHeader) {
        [req setValue:soapHeader_value forHTTPHeaderField:soapHeader_key];
    }

    conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];

    if (conn)
    {
        webData = [NSMutableData data];
    }
}

-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *) response
{
    [webData setLength: 0];
}

-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *) data
{
    [webData appendData:data];
}

-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *) error
{
    didGetError = 1;
    NSLog(@"\n\nConnection Error: %@", error);
}

-(void) connectionDidFinishLoading:(NSURLConnection *) connection
{
    resultXML = [[NSString alloc] initWithBytes:[webData mutableBytes]
                                                length:[webData length]
                                              encoding:NSUTF8StringEncoding];
    didGetError = 0;
    NSLog(@"\n\nRESPONSE XML: %@", resultXML);    
}

+ (BOOL)prepareParsingAndGetResponse
{
    NSInteger isParsingOK;
    isParsingOK = [[self sharedXML] startParsing];

    if (isParsingOK == 1) {
        return YES;
    } else {
        return NO;
    }
}

- (NSInteger)startParsing
{
    @try {
        xmlParser = [[NSXMLParser alloc] initWithData:webData];
        [xmlParser setDelegate:self];
        [xmlParser setShouldResolveExternalEntities:YES];
        [xmlParser parse];
    }
    @catch (NSException *exception) {
        didGetError = 1;
        exceptionReason = exception.reason;
        NSLog(@"Exception Reason: %@", exception.reason);
    }

    if (didGetError != 1) {
        didGetError = 0;
    }

    return didGetError;
}

+ (NSString *)getXMLString
{
    return resultXML;
}

+ (BOOL)isParsingOK
{
    if (didGetError == 1) { // We have error
        return 1;
    } else { // We don't have error
        return 0;
    }
}

+ (NSString *)getResponse
{
    return returnedString;
}

#pragma mark - Start Parsing

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    NSLog(@"START PARSING!");
    if ([elementName isEqualToString:matchingElement]) {
        if (!soapResults) {
            soapResults = [[NSMutableString alloc] init];
        }
        elementFound = YES;
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if (elementFound) {
        [soapResults appendString:string];
        NSLog(@"\n\nsoapResults: %@", soapResults);
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:matchingElement]) {
        returnedString = soapResults; // Save the element we found
        elementFound = NO;
    }
}

@end

我设法发送并取回正确的 xml,但它实际上并没有开始解析。知道如何解决吗?

4

1 回答 1

1

您正在启动异步NSURLConnection,然后立即开始解析过程。您需要将解析的启动推迟到connectionDidFinishLoading,或者您应该进行同步NSURLConnection(但显然,不是来自主队列)。因此,当您最终得到响应时,解析无疑是在收到响应之前启动的。

于 2013-05-24T13:52:05.223 回答