带有编码数据的NSXMLParser

时间:2013-11-18 12:48:07

标签: ios nsstring nsdata nsxmlparser

我想编写一个NSXMLParser,我的数据位于NSString(编码)中。

如果我把NSString放到NSLog它给我正确的线路我需要。但是当我想用来自NSString的数据启动Parser时,它就无法启动。

这是我的代码:

界面:

@interface StundenplanParser () <NSXMLParserDelegate>



@end

从ViewController调用的方法:

    -(void)parserStart
{
    // Create your request string with parameter name as defined in PHP file
    NSString *myRequestString = [NSString stringWithFormat:@"matr=%@&pressme=%@",@"33886",@"S T A R T"];

    // Create Data from request
    NSData *myRequestData = [NSData dataWithBytes: [myRequestString UTF8String] length: [myRequestString length]];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: @"http://www2.htw-dresden.de/~rawa/cgi-bin/auf/raiplan_app.php"]];
    // set Request Type
    [request setHTTPMethod: @"POST"];
    // Set content-type
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
    // Set Request Body
    [request setHTTPBody: myRequestData];
    // Now send a request and get Response
    NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil];
    // Log Response
    NSString *response = [[NSString alloc] initWithBytes:[returnData bytes] length:[returnData length] encoding:NSASCIIStringEncoding];
NSLog(@"Response:%@\n",[response substringToIndex:64]);

    // If I would use NSASCIIStringEncoding in the following line, the data would be nil
    NSData *data = [response dataUsingEncoding:NSUTF8StringEncoding];

    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    if (!parser) NSLog(@"Error with parser");
    else NSLog(@"parser successfully initialised");

    [parser setDelegate:self];
    [parser parse];
}

注意:在我的响应中(NSString *)是我要解析的代码。如果我使用NSLog打印出来,我会看到网站的源代码..

现在我想只显示NSXMLParser发现的元素:

-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    NSLog(@"found element: %@", elementName);
}

我希望我在代码中留下网址不是问题。我只想解析我大学的日程安排。

我希望你理解我的意思,你可以帮助我。

编辑:我的问题不在于我没有得到XML。我的问题是解析器无法启动..我编辑了代码。

EDIT2:响应的输出是:

2013-11-18 23:52:16.008 University[17210:70b] Response:
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN

所以它似乎有效,但问题是将其编码为我需要初始化我的解析器的NSData实例。

EDIT3:

实现解析器之后:parseErrorOccurred我在控制台中收到以下错误:

2013-11-19 08:58:26.190 University[17458:70b] ERROR while parsing: The operation couldn’t be completed. (NSXMLParserErrorDomain error 65.)

3 个答案:

答案 0 :(得分:1)

翻译Google,网站

http://www2.htw-dresden.de/~rawa/cgi-bin/auf/raiplan_app.php

说“以csv格式创建日程表”并输入代码33886中的预算编号,它会返回一个网页,其中包含您想要获取的数据:

  <Stunde>
         <titel>Englisch C1 III/SI (w.o.)</titel>
         <kuerzel>Engl_C1 Üw3/SI Technik</kuerzel>
         <raum>S 334</raum>
         <dozent>Kilian</dozent>
         <datum>16.10.2013</datum>
         <anfang>7:30</anfang>
         <ende>9:00</ende>
  </Stunde>

如果您提取此数据并形成新的XML字符串,则XML Parser将运行。标签是这个数据开始的地方,最后一个标签后跟一个
,所以这段代码将提取元素:

NSRange startRange = [dataString rangeOfString:@"<Stunde>"];
NSString *dataAfterHtml = [dataString substringFromIndex:startRange.location];

NSRange endRange = [dataAfterHtml rangeOfString:@"<br>"];
dataAfterHtml = [dataAfterHtml substringToIndex:endRange.location];

NSString *formattedXML = [NSString
                          stringWithFormat:@"<data>%@</data>",
                          dataAfterHtml];

现在给它解析器

NSData *data = [formattedXML dataUsingEncoding:NSUTF8StringEncoding];
xmlParser = [[NSXMLParser alloc] initWithData:data];

答案 1 :(得分:0)

你的问题是你不是URLEncoding数据,而是将它提取到HTTP正文。在这:

NSMutableData *body = [NSMutableData data];
NSString *postWerte = @"matr=XXXXX&lang=1&aktkw=1&pressme=S T A R T";
[body appendData:[postWerte dataUsingEncoding:NSUTF8StringEncoding]];

你需要URLEncode“S T A R T”,并且应该真正对每个跟随等号的字符串进行URL编码。 (更新:所以它按原样运行 - 我的服务是选择器,我必须编码.YMMV!)

编辑: 所以尝试稍微改变你的代码,如果它仍然失败,那么请发布返回数据的第一行或第二行:

NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil];
assert(returnData); // you should be suppling an error pointer just in case but this will do for now

// Log Response
{
  NSString *response = [[NSString alloc] initWithBytes:[returnData bytes] length:[returnData length] encoding:NSASCIIStringEncoding];
  NSLog(@"%@",[response substringToIndex:64]); // or a bit mor
}


NSXMLParser *parser = [[NSXMLParser alloc] initWithData: returnData];
assert(parser); // will be nil if anything has gone wrong, obviously in your real code put an if test
[parser setDelegate:self]; // no affect for nil object
[parser parse];// no affect for nil object

EDIT2:

顺便说一下,我错过了这个,它可能没什么区别,但解析器对象没有属性“委托”,你在技术上应该使用setter:

[parser setDelegate:self];

另外,你确实实现了以下内容,对吗?

parserDidStartDocument: // which I assume you never see, right
parser:validationErrorOccurred:
parser:parseErrorOccurred:
parserDidEndDocument: // you never see this either?

如果解析器为nil,则将整个返回的数据转储为UTF8字符串(根据日志代码)。另外,请尝试查找错误:

dispatch_async(dispatch_get_main_queue(), ^
    {
            NSLog(@"PARSE ERROR: %@", [parser parseError]);
    } );

答案 2 :(得分:0)

您将数据解释为ASCII,然后将其编码为UTF8,您将最终得到无效字符串或带有无效字符的字符串。试试这个:

...
NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:returnData];
[parser setDelegate:self];
[parser parse];