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ものはまったく役に立ちません。さらに、フィールドに 1 つではなく複数のテキストのチャンクが含まれる場合 (<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 *currentElement;

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 に答える