0

NSXMLParser を使用して、リモート サーバーから XML データを解析しています。チュートリアルに従って起動して実行しましたが、作成しているオブジェクトにある (NSString *) メンバーはすべて問題ありません。また、次のような XML データから設定する必要がある整数もあります。

<root>
    <child>
        <name> Hello </name>
        <number> 123 </number>
    </child>
    <child>
        <name> World</name>
        <number> 456 </number>
    </child>
</root>

この場合、2 つの「子」オブジェクトを作成します。私は使用しています:

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
      namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    ...
    [aChild setValue:currentElementValue forKey:elementName];
    ...
}

値の設定を委譲します。これが私の問題に到達する場所です。「NSString *name」メンバーは毎回正常に設定されますが、NSInteger を使用すると、「number」を設定しようとするたびに EXC_BAD_ACCESS が発生します。そこで、代わりに「int」を使用してみました。しかし、今はキー値プログラミングを使用できず、ノードを手動で探す必要があります。

if([elementName isEqualToString:@"number"]) {
    aChild.number = [currentElementValue intValue]
}

これは大丈夫です。取得するノードがわかっているので対処できますが、さらに悪化します。チュートリアルのように currentElementValue が "NSMutableString *" の場合、文字列が正しいにもかかわらず、正しい整数が返されません。例えば:

    NSLog(@"NSMutableString Value: %@, and intValue %d\n", currentElementValue, [currentElementValue intValue]); 
// Value will be 123 but intValue will be 0

そこで、currentElementValue を NSMutableString ではなく NSString にすると、適切な intValue を取得できます。しかし、それが NSMutableString である理由は次のとおりであることをオンラインで読みました。

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

値を設定するために使用されるデリゲートは複数回発生する可能性がありますが、通常は発生しません。だから私の質問は、私が間違っていることを誰かが知っていますか? これは NSXMLParser のかなり些細なケースのように思えるので、私が誤解しているものだと確信しています。

4

3 に答える 3

2

あなたのコードがどこで失敗しているのかわかりませんが、これを処理する正しい方法は次のとおりです。

NSMutableString *buffer = [[NSMutableString alloc] init];

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
    [buffer setString:@""];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if([elementName isEqualToString:@"number"]) {
        [aChild setNumber:[buffer intValue]];
        [buffer setString:@""];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    [buffer appendString:string];
}
于 2009-04-14T12:24:40.993 に答える
2
  1. intValueNSStringと同じように動作するはずですNSMutableString。文字列が 10 進数で始まらない場合、値は '\n123' (\n は改行文字を意味します) ではなく '123' でしたかintValue?

  2. で可変文字列を正しくクリアしていparser:didStartElement:ますか? でのみクリーニングする場合はparser:didEndElement:parser:foundCharacters:親要素からも文字を収集します。この場合、文字列の前に改行を追加し、intValue0 を返します。

  3. parser:foundCharacters:単一の要素に対して複数回呼び出すことができるという点で、あなたは正しいです。

于 2009-04-14T12:37:48.887 に答える
1

ここでいくつかのことが起こっています。

まず、XML 文字データに明らかな空白があります。

        <number> 456 </number>

その空白を本当に削除する必要があります。[NSString intValue]それが の戻り値が間違っている原因である可能性があります。ソースでそれを削除できれば、素晴らしいです。そうでない場合は、次のようにして、受信側でそれを取り除くことができます。

currentElementValue = [currentElementValue stringByTrimmingCharactersInSet:
    [NSCharacterSet whitespaceAndNewlineCharacterSet]];

キー/値を使用できなかった理由は、NSInteger 値を NSMutableDictionary に格納できないためです。ディクショナリのキーと値はどちらも NSObject から派生する必要があり、NSInteger は (ここでは推測していますが) int のプラットフォーム セーフな typedef にすぎません。したがって、代わりに NSNumber を使用する必要があります。

NSNumber *theInt = [NSNumber numberWithInt:[currentElementValue intValue]];
[aChild setObject:theInt forKey:elementName];
于 2009-04-16T07:42:44.227 に答える