1

我有一个需要解析的 XML 文件。我之前解析过一个 XML,但它更简单。因为这个文件有类似的标签,我不知道如何解析它。

xml 文件如下所示:

<resource classname="Quote">
<field name="name">USD/KRW</field>
<field name="price">1104.319946</field>
<field name="symbol">KRW=X</field>
<field name="ts">1350544190</field>
<field name="type">currency</field>
<field name="utctime">2012-10-18T07:09:50+0000</field>
<field name="volume">-56144</field>
</resource>

我想获取价格字段并将其添加到数组中。我从一些在线示例中尝试了下面的代码,但它显示了所有字段的值,我只想要该price字段。

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

    if ([[attributeDict objectForKey:@"name"] isEqualToString:@"price"])
    {

        currencyValuesString = [[NSMutableString alloc]init];
    }

}


- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementname isEqualToString:@"field"]) 
    {
        [currencyValuesArray addObject:currencyValuesString];
    }
}

- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    currencyValuesString = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
4

2 回答 2

2

您的代码存在多个问题:

  • currencyValuesString你在输入标签时分配/初始化<field name="price">,但你永远不会释放它(如果你不使用 ARC,它会泄漏),更重要的是你不使用这个分配的实例,因为你用-parser:foundCharacters:替换这个变量的值不同的字符串。
  • 因此,先前分配NSMutableString的完全没有用。此外,如果您的字段包含多个文本块而不是一个(<field name="price">1.234<b>€&lt;/b></field>例如),-parser:foundCharacters:将被多次调用,但您的代码将始终丢弃前一个值并仅保留最后一个块而不是将它们添加到NSMutableString.
  • 如果事实上,使用您的代码没有意义,NSMutableString因为您不将其用作可变字符串,而是每次将每个值替换为新值而不是附加它。

而且,每次遇到结束</field>标签时,无论这个标签是什么,您都会执行[currencyValuesArray addObject:currencyValuesString];但不释放currencyValuesString(仅当您使用 ARC 时这很好,但如果您使用手动引用计数会泄漏),更重要的是,您将添加每次遇到结束</field>标签时,无论开始标签是什么,都会将此字符串添加到数组name中。因此,您将价格添加到数组中的次数与</field>价格之后的结束标签一样多。

所以正确的方法是:

  • 将 foundCharacters 附加到您的NSMutableString而不是替换它
  • 当您遇到结束标签时,将价格添加到数组中,然后立即释放并将价格字符串设置回nil。这种方式currencyValuesString只会在<field name="price">开始标签和相应的</field>结束标签之间,而不是在解析其他<field>标签时
  • currencyValuesString如果不是,仅将价格添加到结束标记中的数组中nil

- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if ([[attributeDict objectForKey:@"name"] isEqualToString:@"price"])
    {
        currencyValuesString = [[NSMutableString alloc]init];
    }
}

- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    [currencyValuesString appendString:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
}

- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementname isEqualToString:@"field"] && (currencyValuesString != nil)) 
    {
        [currencyValuesArray addObject:currencyValuesString];
        [currencyValuesString release]; // Only needed if not using ARC. Remove this line if you use ARC
        currencyValuesString = nil; // so that the next closing tag won't readd the price
    }
}
于 2012-10-18T10:54:38.090 回答
0

试试这个 :

在.h

NSXMLParser *rssParser;

NSDictionary *myAttrDict;

NSString *当前元素;

NSMutableArray *prizeArr;

以 .m 为单位:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if([elementName isEqualToString:@"field"])
    {        
        if([[attributeDict objectForKey:@"name"] isEqualToString:@"price"])
        {
            currentElement = @"price";
        }
        else{
            currentElement = nil;
        }
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if([currentElement isEqualToString:@"price"])
    {
        [prizeArr addObject:string];
    }
    NSLog(@"prizeArr :%@",prizeArr);
}

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

- (void)parserDidEndDocument:(NSXMLParser *)parser
{
}
于 2012-10-18T10:54:17.997 回答