【问题标题】:NSXMLParser with encoded Data in StringNSXMLParser 与字符串中的编码数据
【发布时间】:2013-12-01 15:03:58
【问题描述】:

我想对一个 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);
}

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

我希望你明白我的意思,你可以帮助我。

编辑:我的问题不是我没有得到 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.)

【问题讨论】:

    标签: ios nsstring nsdata nsxmlparser


    【解决方案1】:

    您的问题是您不是对数据进行 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]];
    

    您需要对“S T A R T”进行URLEncode,并且应该对每个等号后面的字符串进行真正的URLencoding。 (更新:所以它按原样工作 - 我的服务是方式选择器,我必须编码。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?
    

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

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

    【讨论】:

    • 嘿,感谢您的提示,但 URLConnection 确实适用于此。我从另一个 ViewController 中的 WebView 中的请求中获取输出。我只想解析该请求中的 html 代码。
    • 我添加了一个 if 事件来控制解析器是否为 nil,但事实并非如此。所以 setDelegate 和 parse 应该做一些动作不是吗?
    • 那么返回的文本是什么样的。它可能没有什么可以解析的。您是否也这样做了“NSXMLParser *parser = [[NSXMLParser alloc] initWithData: returnData]”?如果可以,将所有数据转储到文件中,将其放在 DropBox(或您可以共享的某个段)上。这门课我从来没有遇到过问题。你确实实现了所有的委托方法,对吧?
    • 我对目标 c 很陌生,但几天前我编写了一个解析器,它可以按我的意愿完美运行。但在我几天前遇到的问题中,代码不在 POST-php-script 后面,而只是一个 url。我尝试将 NSData 放入文件并在上传时更新此评论。
    • 我不确定如何将 NSData 写入文件.. :D 我试过 [returnData writeToFile:(NSString*)filePath 但我在任何地方都看不到文件..
    【解决方案2】:

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

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

    【讨论】:

    • 我也认为这是真正的问题。我现在按照你说的尝试了,但是解析器也不起作用..
    【解决方案3】:

    用谷歌翻译网站

    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 解析器将运行。标签是数据开始的地方,最后一个是
    ,所以这段代码会提取出元素:

    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];
    

    【讨论】:

    • 非常好 - 正如我们在池塘这边所说的那样,您完成了作业!
    • 是的,我认为这有效!非常感谢你!只是为了我的学习过程.. NSRange startRange 和 endRange 给了我从第一个 到所有条目之后的第一个
      的所有内容?
    • 是的,从网站返回的 html 被删除到第一个 直到最后一个 如果你将整个 html 保存到磁盘,运行 grep -c 计算 标记并将该计数与完成 xml 解析时要填充的数组进行比较。
    • 谢谢,太好了。我不需要所有这些标签,星期都是一样的。只有两种不同的类型,我必须区分。
    猜你喜欢
    • 2015-08-25
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    相关资源
    最近更新 更多