【问题标题】:NSXMLparser: How to return a string if there's an empty element tag (<foo/>)NSXMLparser:如果有一个空元素标签(<foo/>),如何返回一个字符串
【发布时间】:2012-01-25 00:16:00
【问题描述】:

我设置了一个使用 asmx Web 服务的解析器,而 .NET 正在创建一个关闭元素标记。这是日志中的一个片段:

<Name>This is the Name</Name>
<EmptyString1 />
<EmptyString2 />
<Name2>This is Name2</Name2>

当我使用 foundCharacters 方法时,没有找到任何字符,并且空元素正在由最近找到的字符填充。

例如,当我希望它是一个空字符串或返回一个显示“N/A”的字符串时,and 的字符串是“This is the Name”。

似乎 NSXMLparser 不支持这种类型的结束标记,因为它只是跳过它。你会认为它可以在 didEndElement 方法中被捕获,但它永远不会到达那里,因为当斜线位于 then end 而不是 . 时它看不到它。

如何告诉解析器在遇到这种形式的结束标记时返回一个字符串?

编辑:这是我的代码中的更多内容。据我了解,在大多数情况下,我已经在按照 NJones 的建议做,所以我应该把这个问题更多地集中在这种情况上......

将 NSMutableData 对象设置为 0 清除它

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

webData 是从对 Web 服务的肥皂调用设置的,然后作为字符串放入日志中,这样我就可以看到结果是什么样的(与 NJones "stringToParse" 相同,除了包含soap头)然后将webData发送到解析器。

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [webData appendData:data];
    NSString *soapResponse = [[NSString alloc] initWithData:webData encoding:NSASCIIStringEncoding];
    NSLog(@"webData: %@",soapResponse);
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    if (xmlParser)
    {
        [xmlParser release];
    }
    xmlParser = [[NSXMLParser alloc] initWithData:webData];
    [xmlParser setDelegate:self];
    [xmlParser setShouldProcessNamespaces:YES];
    [xmlParser parse];

    [connection release];
    [webData release];
}

在 didStartElement 中,在“File”标签内,也就是解析所有元素的“WebServiceResult”标签

if ([elementName isEqualToString:@"WebServiceResult"]) 
{   
    if(!soapResults)
    {
        soapResults = [[NSMutableString alloc] init]; //declared in .h
    }
    recordResults = YES;
}

下面,当我在主父标签(WebServiceResult)中时,记录结果现在设置为YES,所以它进入foundCharacters并将字符串设置为@“”然后尝试追加

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSMutableString *)string 
{
    if (recordResults)
    {
        if ([string isEqualToString:@""] || string == nil) {
            [soapResults appendString:@"N/A"];
            NSLog(@"foundResults empty: %@",soapResults);
        }
        else {
            [soapResults setString:@""];
           [soapResults appendString: string];
           NSLog(@"foundResults: %@",soapResults);
        }
    }
}

在 didEndElement 方法中,重要的是要注意 "EmptyString1" 有时不是 EMPTY,因此如果在某处没有某种 if 语句,就不能将 EmptyString 元素设置为 @"",就像上面的 foundCharacters 方法一样。然后将 webData 发送到解析器

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:@"Name"]) 
    {
        name = [NSString stringWithFormat:@"%@",soapResults];
        NSLog(@"Name: %@",name);
    }
        if ([elementName isEqualToString:@"EmptyString1"]) 
    {
       sometimesEmptyString = [NSString stringWithFormat:@"%@",soapResults];
       NSLog(@"EmptyString1: %@",sometimesEmptyString);
    }

        //...and the same goes for sometimesEmptyString2, and name2...
}

因此,总而言之,日志不会进入带有 [string isEqualToString:@""] 的“foundCharacters empty” if 语句,因为当元素标签为空时,它永远不会进入 foundCharacters 方法。这只是为了澄清,如果我的解析器根本没有看到空元素,我不确定如何附加 @"" ......有人会看到我缺少的东西,我确定这是一个从这里简单修复

【问题讨论】:

  • 这不是结束标签,而是empty element tag
  • 我刚刚发现了这个新问题,因为它是 2012 年 1 月 2 日提出的,如果我要处理 50 个不同的元素,这仍然是个问题
  • 感谢昆汀,我更改了问题标题以反映您的评论
  • 虽然 Quentin 链接的问题类似,但它只是询问解析器是否可以处理它。处理是一回事,返回空字符串是另一回事。当然你可以让解析器找到元素,但是当标签为空时,你在哪里以及如何设置一个要填充的变量,因为 foundCharacters 方法被跳过了,标签有时不是空的?

标签: iphone xml asmx nsxmlparser


【解决方案1】:

哇...超级容易解决,但我想通了...

这是 foundCharacters 方法所需的更改

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSMutableString *)string {

    if (string != nil) {
        [soapResults setString:@""];
        [soapResults appendString: string];
        NSLog(@"foundResults: %@",soapResults);
    }

}

然后我在最后将这个简单的部分添加到 didEndElement

[soapMessage setString:@"N/A"];

它的作用是将soapMessage设置为@“N/A”,因此当跳过foundCharacters时,soapMessage保留了@“N/A”,如果有findCharacters,它会清除它并附加字符串到soapMessage,所以它可以在didEndElement 中设置。所以真的,字符串需要在 didEndElement 的末尾设置为你想要的任何内容,而不是在我的特殊情况下在 didStartElement 中。

【讨论】:

    猜你喜欢
    • 2012-04-30
    • 1970-01-01
    • 2020-01-03
    • 2019-10-29
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多