【问题标题】:NSXMLParser didStartElement only with a certain attributeNSXMLParser didStartElement 仅具有特定属性
【发布时间】:2014-03-11 14:31:21
【问题描述】:

话说我了解了用 NSXMLParser 解析 XML 文件的基本原理,我有以下情况,其中我有几个元素 <table_data>...</table_data> 对于某个属性的值彼此不同,所以,例如:

<table_data attr="one">...</table_data> 

<table_data attr="two">...</table_data>

<table_data attr="three">...</table_data>

在 didStartElement 中,我希望解析器仅在具有 attr="one" 时才将 &lt;table_data&gt; 元素视为开始元素。

这意味着在 foundCharacters 中我只能获得 &lt;table_data attr="one"&gt; 的子元素的内容,但不能获得 &lt;table_data attr="two"&gt;&lt;table_data attr="three"&gt; 等的子元素的内容。

现在,我试试这个:

- (void)parser:(NSXMLParser*)parser didStartElement:(NSString *)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary*)attributeDict {

    elementoCorrente = [elementName copy];

    if ([elementName isEqualToString:@"table_data"]) {

        if ([[attributeDict objectForKey:@"attr"] isEqualToString:@"one"]) {
            stringDesc = [[NSMutableString alloc] init];

        }

    }

}


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


    if ([elementoCorrente isEqualToString:@"field"]) {

        [stringDesc appendString:string];
        NSLog(@"%@",string);
    }


}

但我得到的是&lt;field&gt; 元素的内容日志,它是所有&lt;table_data&gt; 的子元素。 如果是 &lt;table_data attr="one"&gt; 的子元素,有没有办法只打印 &lt;field&gt; 元素的内容? 谢谢 法比奥

【问题讨论】:

    标签: ios xml sdk nsxmlparser


    【解决方案1】:

    问题是您没有采取任何措施来阻止foundCharacters 为其他出现的table_data 添加数据。您也可以让您的didStartElement 保存attributeDict[@"attr"] 值,然后foundCharacters 可以检查elementoCorrente 以及您持有attributeDict[@"attr"] 值的这个新ivar。例如:

    - (void)parser:(NSXMLParser*)parser didStartElement:(NSString *)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary*)attributeDict {
    
        elementoCorrente = nil;
        atributoCorrente = nil;
    
        if ([elementName isEqualToString:@"table_data"]) {
    
            if ([attributeDict[@"attr"] isEqualToString:@"one"]) {
                elementoCorrente = [elementName copy];
                atributoCorrente = [attributeDict[@"attr"] copy];
                stringDesc = [[NSMutableString alloc] init];
            }
        }
    }
    
    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    
        if ([elementoCorrente isEqualToString:@"table_data"] && [atributoCorrente isEqualToString:@"one"]) {
    
            [stringDesc appendString:string];
        }
    }
    

    坦率地说,您可能还想要一个didEndElement 实现,它将stringDesc 保存在您想要保存的任何位置,然后将elementoCorrente 设置为nil

    【讨论】:

    • 在我看来,这是正确的答案。令人难以置信的是它是多么容易。真可惜……非常感谢 Rob,他也花时间为我提供了工作代码 :) 另外,Helderdarocha 的回答是一个有效且好的答案,多亏了你们两个,我现在可以继续了!
    【解决方案2】:

    也许代码片段缺少某些内容,但从您在此处显示的内容来看,打印所有 field 标记的内容是预期的行为,因为您在 parser:foundCharacters: 方法中所做的唯一测试是当前元素是field

    您可以使用attr_one 添加一个标志,表明您在table_data 内。比如:

    if ([[attributeDict objectForKey:@"attr"] isEqualToString:@"one"]) {
        stringDesc = [[NSMutableString alloc] init];
        insideTableOne = YES;
    }
    

    然后,在parser:foundCharacters: 中,还要在附加字符串之前测试insideTableOne 是否为真。

    这个测试也是必要的,这样如果你的程序发现没有预期属性的table_data,它就不会崩溃。如果发生这种情况,stringDesc 将不会被实例化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-13
      • 2013-05-27
      • 2012-02-18
      • 2012-10-18
      • 2019-09-29
      • 2016-05-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多