iPhone:如何通过Web服务获取值数组?

时间:2012-04-16 02:44:05

标签: iphone ios web-services ipad nsxmlparser

我在iPhone中使用Web服务并通过NSXMLParser解析它。我的服务返回对象数组,但是当我从Web服务获取它时,它会连接相同类型的值。 Web服务生成以下响应。

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <GetClientTripsResponse xmlns="http://tempori.net/">
      <GetClientTripsResult>
        <TripNumbers>
          <ConfirmationsNumber>string</ConfirmationsNumber>
          <TripState>string</TripState>
        </TripNumbers>
        <TripNumbers>
          <ConfirmationsNumber>string</ConfirmationsNumber>
          <TripState>string</TripState>
        </TripNumbers>
      </GetClientTripsResult>
    </GetClientTripsResponse>
  </soap:Body>
</soap:Envelope> 

对于ConfirmationsNumber是6位数,TripState是字符串值NONE或ONWAY

但是当我解析它时会给出

ConfirmationsNumber = 234589455623784523和

TripState = NONENONEONWAY

表示它解析三个对象并将它们连接起来。我希望有孤立的值或至少逗号分隔。像234589,455623,784523或者什么,但应该分开。

以下是代码

@interface TrackTripStatus : UITableViewController <NSXMLParserDelegate> {
    NSMutableArray *tripList;
    UILabel *noTripsLabel;
    int indexCount;
    BOOL elementFound;

    // for Web service
    NSMutableData *webData;
    NSMutableString *soapResults;
    NSURLConnection *conn;
    NSXMLParser * xmlParser;
    NSString * qelementName;
    NSString * RequestStep;
}

- (void) getClientTrips;
-(void) setControls;
@end

- (void) getClientTrips
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *CLIENTPHONENUMBER = [defaults stringForKey:@"CLIENTPHONENUMBER"];
    if(CLIENTPHONENUMBER == nil)
        CLIENTPHONENUMBER = @"";

    NSString *soapMsg = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
                         "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
                         "<soap:Body>"
                         "<GetClientTrips xmlns=\"http://tempori.net/\">"
                         "<HomePhone>%@</HomePhone>"
                         "</GetClientTrips>"
                         "</soap:Body>"
                         "</soap:Envelope>",CLIENTPHONENUMBER]; 

    NSURL *url = [NSURL URLWithString: WebServiceURL];
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];

    NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMsg length]];
    [req addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [req addValue:@"http://Itcurves.net/GetClientTrips" forHTTPHeaderField:@"SOAPAction"];
    [req addValue:msgLength forHTTPHeaderField:@"Content-Length"]; //---set the HTTP method and body--- 
    [req setHTTPMethod:@"POST"]; 
    [req setHTTPBody:[soapMsg dataUsingEncoding:NSUTF8StringEncoding]];

    NSLog(@"%@\n", soapMsg); 
    RequestStep = @"GetClientTripsResult";
    if (conn) {
        [conn release];
    }

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

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


-(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 {
    NSLog(@"Test: %@", error);
    [webData release]; 
    [connection release];
}

-(void) connectionDidFinishLoading:(NSURLConnection *) connection 
{ 
    NSLog(@".........DONE. Received Bytes: %d", [webData length]); 
    NSString *theXML = [[NSString alloc]    //---shows the XML---
                        initWithBytes:[webData mutableBytes] length:[webData length]
                        encoding:NSUTF8StringEncoding];
    NSLog(@"\n\n %@",theXML);
    if([theXML length] < 120)
    {
        if(indexCount < 3)
        {
            if([RequestStep isEqualToString:@"GetClientTripsResult"])
                [self SendClientInfo];
            indexCount = indexCount +1;
        }
        else {
            RequestStep = @"end";
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Result" message:@"Server was unable to process request" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
            [alert show]; 
            [alert release];
        }

    }   

    [theXML release];                                                                                       


    /*  CODE TO RELEASE XML start  */
    if (xmlParser) 
    { 
        [xmlParser release];
    }
    [soapResults setString:@""]; 

    xmlParser = [[NSXMLParser alloc] initWithData: webData]; 
    [xmlParser setDelegate:self]; 
    [xmlParser setShouldResolveExternalEntities:YES]; 

    /*  CODE TO RELEASE XML end  */
    NSLog(@"Step: %@, %@",RequestStep, soapResults);
    if([RequestStep isEqualToString:@"GetClientTripsResult"])
    {
        qelementName = @"ConfirmationsNumber";
        [xmlParser parse];
        if ([soapResults length]> 0) 
        {
            NSString * ConformNo = soapResults;
            qelementName = @"TripState";
            [soapResults setString:@""];
            [xmlParser parse];
            if ([soapResults length] > 1) {
                NSLog(@"Step2: %@, %@",RequestStep, soapResults);
                indexCount =0;
                RequestStep = @"end";



            }
            else{               
                qelementName = @"DeclineReason";
                [soapResults setString:@""];
                [xmlParser parse];
                RequestStep = @"end";               
            }
        }
    }   
    if([RequestStep isEqualToString: @"end"])
    {
        //  [connection release];                                                                                                                                    
        //  [webData release];      
    }
}

2 个答案:

答案 0 :(得分:0)

我使用名为sudzc的库,它生成了Web服务的所有方法,因此您不必解析服务器响应并直接获得可以使用的数组。

答案 1 :(得分:0)

每当我使用NSXMLParser时,我都会使用回调来解析它。这是我用于此的代码:

首先设置委托和类变量

@interface FooBarClass : UIViewController <NSXMLParserDelegate>
{
    NSMutableString *currentElementValue;
}

然后你需要获取网址并设置xmlparser

NSString *address = [[NSString alloc] initWithString:@"http://somewebservice"];
NSURL *url = [[NSURL alloc] initWithString:address];

NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];

[url release];

[xmlParser setDelegate:self];

[xmlParser parse];
[xmlParser release];

然后是回调:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
{

if([elementName isEqualToString:@"Foo"]) {  //start of main element to save
    if (Bar) 
    {
        [Bar release];
        Bar = nil;
    }
    Bar = [BarType alloc];
}

//finding characters in an element. could be multiple calls so append here
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
{

if(!currentElementValue)
    currentElementValue = [[NSMutableString alloc] initWithString:string];
else
    [currentElementValue appendString:string];
}

//ending elements
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
{

NSString *trimmedValue = [currentElementValue stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

if([elementName isEqualToString:@"Foo"])   //this is the end of the top level object so add it to our array
{
    [fooArray addObject:Bar];

}
else if([elementName isEqualToString:@"Foo2"])  //this is one of the features so we set it in our object
{
    Bar.fooBarString = trimmedValue;
}



[currentElementValue release];  //release this to make room for the next element
currentElementValue = nil;
}