[ Valerij Zajcev @ 19.10.2010. 09:53 ] @
Znaci ubi me ovo... napravio sam iPhone aplikaciju koja se kaci na neki web service (asmx) preko SOAP-a i dovucem XML sa rezultatima. Njega stavim u NSMutableData objekat. Problem je sto mi je XML u malo cudnom formatu:
Code:

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><GetWeatherResponse xmlns="http://www.webserviceX.NET"><GetWeatherResult>&lt;?xml version="1.0" encoding="utf-16"?&gt;
&lt;CurrentWeather&gt;
  &lt;Location&gt;BERLIN MUNICIPAL AIRPORT, NH, United States (KBML) 44-35N 71-11W 345M&lt;/Location&gt;
  &lt;Time&gt;Oct 19, 2010 - 03:52 AM EDT / 2010.10.19 0752 UTC&lt;/Time&gt;
  &lt;Wind&gt; Calm:0&lt;/Wind&gt;
  &lt;Visibility&gt; 10 mile(s):0&lt;/Visibility&gt;
  &lt;SkyConditions&gt; clear&lt;/SkyConditions&gt;
  &lt;Temperature&gt; 23.0 F (-5.0 C)&lt;/Temperature&gt;
  &lt;DewPoint&gt; 21.0 F (-6.1 C)&lt;/DewPoint&gt;
  &lt;RelativeHumidity&gt; 91&lt;/RelativeHumidity&gt;
  &lt;Pressure&gt; 29.83 in. Hg (1010 hPa)&lt;/Pressure&gt;
  &lt;Status&gt;Success&lt;/Status&gt;
&lt;/CurrentWeather&gt;</GetWeatherResult></GetWeatherResponse></soap:Body></soap:Envelope>

I sada kada didRootElement metoda pregleda ovaj XML ne prepozna CurrentWeather kao root tag. Probao sam da castujem NSMutableData u NSString i da uradim replace ali ne znam kako posle to da vratim u NSMutableData. Cudno je da NSXmlParser sam ne prepoznaje ovo, znaci ima li nacina da se ovo nekako sredi?
[ madamov @ 19.10.2010. 10:28 ] @
Strogo uzevši, ovo i nije XML, tj. svako &lt; i &gt; treba zameniti sa "<" i ">", parser jednostavno ne prepoznaje nijedan element.

Pitanje je gde je tačno problem, a da bi to utvrdio moraš da ideš nisko sa nekim packet tracerom (ako baš ne nađeš nijedan tu je uvek tcpdump iz Terminala) da vidiš šta ti tačno dolazi sa druge strane. Ako je druge strane sve u redu, a verujem da jeste, onda lovi grešku kod sebe. Nego, ako nije tajna, koji je tačno URL web servisa da probam ja 4D-om da povučem XML, ako on uspe onda je sve u redu sa serverom?
[ Valerij Zajcev @ 19.10.2010. 10:40 ] @
Ovo je servis http://www.webservicex.com/globalweather.asmx?op=GetWeather on je apsolutno u redu lepo on vraca ali mi u aplikaciju dodje xml sa tako sastavljenim tagovima.
Ovako prikazujem da vidim sta mi je u webData posto tu stavljam podatke sa WS-a.
Code:

NSString *theXML = [[NSString alloc] 
                        initWithBytes: [webData mutableBytes] 
                        length:[webData length] 
                        encoding:NSUTF8StringEncoding];
    //---shows the XML---
    NSLog(theXML);

Onda parser
Code:

...
xmlParser = [[NSXMLParser alloc] initWithData: webData];
                [xmlParser setDelegate:self];   
                [xmlParser setShouldResolveExternalEntities:YES];
                [xmlParser parse];
...
-(void) parser:(NSXMLParser *) parser 
    didStartElement:(NSString *) elementName 
    namespaceURI:(NSString *) namespaceURI 
    qualifiedName:(NSString *) qName
    attributes:(NSDictionary *) attributeDict {


    NSLog(elementName);
    if( [elementName isEqualToString:@"GetWeatherResult"])
    {
        if (!soapResults)
        {
            soapResults = [[NSMutableString alloc] init];
        }
        elementFound = YES;
    }
...

I ovde gde ispituje ko je node vidi samo envleope, body i GetWeatherResult a ostatak ne vidi verovatno zbog toga sto stoje ti cudni elementi :(
[ Dachaz @ 19.10.2010. 12:17 ] @
Uzmi sadržaj GetWeatherResult kao string; ručno konvertuj &lt; i &gt; (kao što ti je Miki rekao); učitaj taj string kao XML objekat i eto ti.
Vrlo je verovatno da postoje već gotove metode za raspakivanje SOAP poruka, ali dok ih ne nađeš, snađi se ovako.
[ Valerij Zajcev @ 19.10.2010. 12:40 ] @
Napravio sam jos jedan NSXmlParser posto je rezultat obavijen u tom tagu get result i kada se iscita sadrzaj iz tog taga dobijem XML koji meni treba kada ga castujem u NSMutableString. Sada mi je problem da taj string castujem u NSData. Probao sam ...
Code:

NSData *wData = [soapResults dataUsingEncoding:NSUTF8StringEncoding];
                
        NSLog(wData);

Ali dobijam sledecu gresku:
Code:

terminate called after throwing an instance of 'NSException'
Program received signal:  “SIGABRT”.

[ madamov @ 19.10.2010. 12:44 ] @
Citat:
Valerij Zajcev
I ovde gde ispituje ko je node vidi samo envleope, body i GetWeatherResult a ostatak ne vidi verovatno zbog toga sto stoje ti cudni elementi :(

Problem nije u parseru, već u SOAP komunikaciji na prijemnoj (tvojoj) strani, treba ustanoviti ko, tj. šta, obavlja on-the-fly konverziju poslatog "<" u &lt;.
[ madamov @ 19.10.2010. 12:47 ] @
Citat:
Valerij Zajcev: Napravio sam jos jedan NSXmlParser posto je rezultat obavijen u tom tagu get result i kada se iscita sadrzaj iz tog taga dobijem XML koji meni treba kada ga castujem u NSMutableString. Sada mi je problem da taj string castujem u NSData. Probao sam ...
Code:

NSData *wData = [soapResults dataUsingEncoding:NSUTF8StringEncoding];

NSLog(wData);

Ali dobijam sledecu gresku:
Code:

terminate called after throwing an instance of 'NSException'
Program received signal:  “SIGABRT”.


Ne možeš na silu, rešavaš posledicu, a ne uzrok. Jedini validan workaround je ovo što ti je Dača rekao, konvertuj tekst sam pa ga prosledi parseru kao XML fajl. Međutim, nisi rešio uzrok problema i imaćeš i dalje problem, nešto si pogrešno uradio kod komunikacije, pogledaj dokumentaciju SOAP biblioteke ili frameworka koji si koristio.
[ madamov @ 19.10.2010. 13:00 ] @
A pogledaj i ovo: http://sudzc.com/
[ Valerij Zajcev @ 19.10.2010. 14:21 ] @
Ja mislim da uzrok bas dolazi sa servisa jer evo sta dobijem direktno sa servisa, znaci cim pozovem metodu i nista ne menjam:
Code:

(gdb) x/10s (char *)[self.webData bytes]
0x703da00:     "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLS"...
0x703dac8:     "chema\"><soap:Body><GetWeatherResponse xmlns=\"http://www.webserviceX.NET\"><GetWeatherResult>&lt;?xml version=\"1.0\" encoding=\"utf-16\"?&gt;\r\n&lt;CurrentWeather&gt;\r\n  &lt;Location&gt;BERLIN MUNICIPAL AIR"...
0x703db90:     "PORT, NH, United States (KBML) 44-35N 71-11W 345M&lt;/Location&gt;\r\n  &lt;Time&gt;Oct 19, 2010 - 07:52 AM EDT / 2010.10.19 1152 UTC&lt;/Time&gt;\r\n  &lt;Wind&gt; Calm:0&lt;/Wind&gt;\r\n  &lt;Visibility&g"...
0x703dc58:     "t; 10 mile(s):0&lt;/Visibility&gt;\r\n  &lt;SkyConditions&gt; clear&lt;/SkyConditions&gt;\r\n  &lt;Temperature&gt; 26.1 F (-3.3 C)&lt;/Temperature&gt;\r\n  &lt;DewPoint&gt; 24.1 F (-4.4 C)&lt;/DewPoint&gt;\r"...
0x703dd20:     "\n  &lt;RelativeHumidity&gt; 92%&lt;/RelativeHumidity&gt;\r\n  &lt;Pressure&gt; 29.86 in. Hg (1011 hPa)&lt;/Pressure&gt;\r\n  &lt;PressureTendency&gt; 0.03 inches (0.9 hPa) higher than three hours ago&lt;/"...
0x703dde8:     "PressureTendency&gt;\r\n  &lt;Status&gt;Success&lt;/Status&gt;\r\n&lt;/CurrentWeather&gt;</GetWeatherResult></GetWeatherResponse></soap:Body></soap:Envelope> [Message <?xml version=\"1.0\" encoding=\"utf-8\"?"...
0x703deb0:     "><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><GetWeather xmlns=\""...
0x703df78:     "http://www.webserviceX.NET\"><CityName>Berlin</CityName><CountryName>united states</CountryName></GetWeather></soap:Body></soap:Envelope>] [CFLog\\sLocal\\sTime 2010-10-19 14:15:57.700] [CFLog\\sThread 20"...
0x703e040:     "7] [ReadUID 502] [TimeNanoSec 701587000] [Facility com.apple.console]"
0x703e086:     '\377' <repeats 51 times>, "\227"
[ madamov @ 19.10.2010. 14:49 ] @
A kako pozivaš servis?

Nisam stručnjak za iOS, ali meni sve liči da ti simuliraš da si Web browser i da onda dobijaš u startu konvertovane "<", kako kada bi puštao browseru da ti prikaže HTML kod koji će on pokušati da interpretira.
[ Valerij Zajcev @ 20.10.2010. 08:54 ] @
WS pozivam preko SOAP-a. Dakle pustim parser da nadje GetWeatherResults a onda ono sto se nadje tu castujem u nsstring i dobijem ispravan rezultat. Onda taj rezultat pustim kroz parser i sve je u redu :)
[ madamov @ 20.10.2010. 12:33 ] @
To si rekao i u prvoj poruci, da si koristio SOAP, ali koji si framework koristio nisi rekao, tako da je sada problem delimično rešen, ali još nisi rešio problem šta ti je menjalo ">" u &gt;. Koliko je meni poznato, SOAP server ne bi smeo da šalje response koji umesto "<" šalje &lt; pa da ti moraš dodatno da konvertuješ response.
[ Valerij Zajcev @ 20.10.2010. 13:01 ] @
Nisam koristio nikakav framework direktno sam sve radio iz objective c-a...
Code:

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>"
     "<GetWeather xmlns=\"http://www.webserviceX.NET\">"
     "<CityName>%@</CityName>"
     "<CountryName>%@</CountryName>"
     "</GetWeather>"
     "</soap:Body>"
     "</soap:Envelope>", cityName.text, @"united states"
     ];
    
    
    NSURL *url = [NSURL URLWithString: 
                  @"http://www.webservicex.com/globalweather.asmx"];
    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://www.webserviceX.NET/GetWeather" 
forHTTPHeaderField:@"SOAPAction"];
    [req addValue:msgLength forHTTPHeaderField:@"Content-Length"];
       
    [req setHTTPMethod:@"POST"];
    [req setHTTPBody: [soapMsg dataUsingEncoding:NSUTF8StringEncoding]];
    
    // start animationg activity indicator before make the actual ws call
    [activityIndicator startAnimating];    
    
    conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
    if (conn) {
        webData = [[NSMutableData data] retain];
    }  
    NSLog(@"%@", webData);



Code:

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

-(void) connection:(NSURLConnection *) connection 
    didReceiveData:(NSData *) data {
    [webData appendData:data];
    NSLog(@"%@", webData);
}

-(void) connection:(NSURLConnection *) connection 
  didFailWithError:(NSError *) error {
    [webData release];    
    [connection release];
}

-(void) connectionDidFinishLoading:(NSURLConnection *) connection {
    NSLog(@"DONE READING WEATHER WEB SERVICE. Received Bytes: %d", [webData length]);
    NSString *theXML = [[NSString alloc] 
                        initWithBytes: [webData mutableBytes] 
                        length:[webData length] 
                        encoding:NSUTF8StringEncoding];      
    [theXML release]; 
    
    //-----------------------------------------------------------------
    // start parsing received XML message
    //-----------------------------------------------------------------
    if (xmlParser)
    {
        [xmlParser release];
    }
    xmlParser = [[NSXMLParser alloc] initWithData: webData];
    [xmlParser setDelegate:self];    
    [xmlParser setShouldResolveExternalEntities:YES];
    [xmlParser parse];
        
    // clear memory
    [connection release];
    [webData release];
}


[ madamov @ 20.10.2010. 13:23 ] @
Onda u tome i jeste problem. Jeste da SOAP ide preko HTTP protokola (pojednostavljeno: XML isporučen preko HTTP-a), ali ne bi smeo da pristupaš SOAP serveru na isti način kao što browser pristupa bilo kom Web serveru, zato si i dobio &lt; umesto "<", a pitanje je i koji bi se još ostali karakteri u XML-u promenili. No, važno je da radi. B)
[ Valerij Zajcev @ 20.10.2010. 13:29 ] @
Ja sam jos nov u celoj ovoj prici u iPhone-u. Ima li bolji nacin (pravilniji) da se pristupi servisu i povuku podaci od ovog na koji sam ja radio?
[ bilbija @ 05.11.2010. 22:59 ] @
A kako dobijas XML rezultat? Zanima me , recimo spisak restorana u odredjenoj zoni ili gradu na primer. Kako da dodjem do toga?
[ madamov @ 07.11.2010. 22:49 ] @
Nađeš Web Service koji to nudi. Ako ga uopšte ima za kraj koji te interesuje.
[ bilbija @ 11.11.2010. 16:07 ] @
Pa nemam odredjeni polozaj. iPhone nadje svoju lokaciju i na osnovu te lokacije mi trebaju recimo restorani u krugu od 2-3 km. IOli pèarkinzi, nije vazno. Ali kako dobiti to od Googla? To me zanima i treba mi.
[ madamov @ 11.11.2010. 20:16 ] @
Za početak treba da saznaš na koji način Google publikuje tu informaciju. Tek posle razmišljaj šta da radiš na iPhoneu.
[ bilbija @ 12.11.2010. 03:42 ] @
Pa to i jeste moje pitanje. Gde googl to publikuje, to me zanima. S iPhone sam pomenuo kao primer.
[ madamov @ 12.11.2010. 10:09 ] @
Odeš na Google pa tražiš. Ili im pošalješ mail.