【问题标题】:Parsing Webservice data iOS解析Webservice数据iOS
【发布时间】:2012-06-21 13:42:53
【问题描述】:

大家下午好,

我已经从 Web 服务下载了数据,我希望解析这些数据以便我可以使用它,但是我在解析返回的值时遇到了问题,下面是获取代码以及介于两者之间的任何帮助将是赞赏

 -(IBAction)runNewImport:(id)sender{


recordResults = FALSE;

soapMessage = [NSString stringWithFormat:

               @"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"

               "<s:Envelope \n"

               "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" \n"
               "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n" 
               "xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" \n"
               "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" \n"
               "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"> \n"       


               "<s:Body> \n"

               "<[FUNCTION] xmlns=\"http://tempuri.org/\"/>\n"

               "</s:Body> \n"
               "</s:Envelope>"];


[[NSURLCache sharedURLCache] removeAllCachedResponses];
NSURL *url = [NSURL URLWithString:@"http://[PATH]"];      
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];             
NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMessage length]];          
[theRequest addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];       
[theRequest addValue: @"[FUNCTION]" forHTTPHeaderField:@"SOAPAction"];
[theRequest addValue: msgLength forHTTPHeaderField:@"Content-Length"];
[theRequest setHTTPMethod:@"POST"];     
[theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

if(theConnection) {
    webData = [NSMutableData data];
    NSLog(@"%@",webData);
}
else {
    NSLog(@"theConnection is NULL");
}       



}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"DONE. Received Bytes: %d", [webData length]);
NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
NSLog(@"THIS IS THE DATA : %@",theXML);


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
{
if( [elementName isEqualToString:@"CODE"])
{
    soapResults = [[NSMutableString alloc] init];
    NSLog(@"%@",soapResults);
    recordResults = TRUE;
}
}

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)
 elementName namespaceURI:(NSString *)namespaceURI 
  qualifiedName:(NSString *)qName

{
if( [elementName isEqualToString:@"CODE"])
{
    recordResults = FALSE;
    soapResults = nil;
    }
}

感谢再次浏览,欢迎大家帮忙

【问题讨论】:

  • 你忘了说你在解析时遇到了什么问题。
  • 另外,您从NSLog 返回的soapResults 可能是空白的吧?
  • 是的,它甚至没有出现。问题是它没有解析,我已经尝试了一段时间,XML 在那里并且可用,下面找到 XML 文件的示例
  • 36TESTTESTTESTAMN/A0.000.00
  • 它没有显示出来,因为你分配并初始化它然后你 NSLog 它。您永远不会为其分配任何值,您只需 NSLog 您创建的空白字符串。

标签: objective-c ios xml web-services nsxmlparser


【解决方案1】:

您似乎误解了 NSXMLParser 的工作方式。我敦促你好好看看这个来自 Apple 的文档XML parsing

-(void)parser:didStartElement:namespaceURI:qualifiedName:attributes:

当解析器找到像 一样的开始 XML 标记时调用此方法,因此它还没有任何数据。在这里,您只需为要保存的任何内容分配内存

- (void)parser:foundCharacters:

当在parser:didStartElement:namespaceURI:qualifiedName:attributes: 中找到的标记内有数据时调用,这是您首先存储该数据的位置,以便您以后可以在下一个方法中将其保存在所需的对象上:

-(void)parser:didEndElement:namespaceURI:qualifiedName

在解析器遇到结束标记 () 时调用。现在您拥有了保存在 parser:foundCharacters: 变量中的数据,是时候将其保存在您的对象中了。

编辑:好的,让我们尝试通过在这些方法中添加代码示例来分解它:

假设您有一个如下所示的 XML;

<person>
    <lastName>Doe</lastName>
    <firstName>John</firstName>
    <address>
        <street>100 Main Street</street>
        <city>Somewhere</city>
    </address>
</person>

当然,您希望有一个 Person 类,其属性 lastNamefirstNameaddressDictionary 包含 street 城市。要保留所有 Persons,您需要 personArray

现在我们有了结构,这里是解析部分。 请注意,为了更好地理解,我将分别编写每个 If 块。

.h 文件

@property (nonatomic, retain) Person *currentPerson;
@property (nonatomic, retain) NSMutableString *currentElement;
@property (nonatomic, retain) NSMutableDictionary *addressDic; //to be saved to person.addressDictionary when finished
@property (nonatomic, retain) NSMutableArray *personArray;

.m 文件

- (void)parserDidStartDocument:(NSXMLParser *)parser 
{
    personArray = [[NSMutableArray alloc] init];
}

- (void) parser: (NSXMLParser *) parser didStartElement: (NSString *) elementName
 namespaceURI: (NSString *) namespaceURI qualifiedName: (NSString *) qName attributes: (NSDictionary *) attributeDict
{
    if ([elementName isEqualToString:@"Person"])
    {
    currentPerson = [[Person alloc] init]; //
    return;
    }
    if ([elementName isEqualToString:@"lastName"])
    {
        currentElement = [[NSMutableString alloc] init];
        return;
    }
    if ([elementName isEqualToString:@"firstName"])
    {
        currentElement = [[NSMutableString alloc] init];
        return;
    }
    if ([elementName isEqualToString:@"address"])
    {
        adressDic = [[NSMutableDictionary alloc] init];
        return;
    }
    if ([elementName isEqualToString:@"street"])
    {
        currentElement = [[NSMutableString alloc] init];
        return;
    }
    if ([elementName isEqualToString:@"city"])
    {
        currentElement = [[NSMutableString alloc] init];
        return;
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    [currentElement appendString:string];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:@"Person"])
    {
    [personArray addObject:currentPerson];
    [currentPerson release];
    return;
    }
    if ([elementName isEqualToString:@"lastName"])
    {
        currentPerson.lastName = currentElement;
        [currentElement release]; currentElement = nil;
        return;
    }
    if ([elementName isEqualToString:@"firstName"])
    {
        currentPerson.firstName = currentElement;
        [currentElement release]; currentElement = nil;
        return;
    }
    if ([elementName isEqualToString:@"address"])
    {
        currentPerson.addressDictionary = addresDic;
        [addressDic release];
        return;
    }
    if ([elementName isEqualToString:@"street"])
    {
        [addressDic setObject:currentElement forKey:@"street"];
        [currentElement release]; currentElement = nil;
        return;
    }
    if ([elementName isEqualToString:@"city"])
    {
        [addressDic setObject:currentElement forKey:@"city"];
        [currentElement release]; currentElement = nil;
        return;
    }
}

当这一切都完成后,parserDidEndDocument: 被调用。现在你的数组中已经有了所有的Persons,你可以随心所欲地使用它们

- (void)parserDidEndDocument:(NSXMLParser *)parser
{
     for (Person *person in personArray)
     {
          NSLog(@"Person name:%@", person.firstName);
          NSLog(@"Person lastname:%@", person.lastName);
     }
}

【讨论】:

  • 谢谢,但你会如何改变它?我问是因为我有 XML 解析的经验,因为我之前已经做过一些事情,但我无法让它工作
  • 改一下是什么意思?
  • 这真是太棒了,我从来没有人这么想帮助过我,但是唉,这是现实世界,它仍然无法正常工作,我感觉它与我收到的 xml 格式,我在顶部发布了一个示例,试图让其他人理解,我觉得这将是一个漫长的夜晚:/为精彩的答案竖起大拇指
  • 欣赏你的赞美之词。由于帮助的唯一目的还没有达到,我会坚持寻找解决方案。首先,当你写 isEqualToString:@"a:ECRMPERSONNEL" 时它也不起作用,尝试 NSLog 只在 parser:didStartElement:... 中的 elementName 并告诉我日志说什么
  • 我在元素名称上尝试了 NSLog,但它甚至没有出现在调试器控制台中,
猜你喜欢
  • 1970-01-01
  • 2013-02-08
  • 1970-01-01
  • 1970-01-01
  • 2015-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多