Sudzc deserializeAsDictionary: переписанный словарь
Сгенерированный Sudzc код завершает написание словаря для десериализованных узлов. Если я использую NSLog(@"Дочерний узел: %@", [[[element children] objectAtIndex:0] stringValue]); он будет писать правильные элементы каждый раз, когда он прошел. Когда я пытаюсь получить результаты в коде, доступен только последний (Джексон 3). Что я делаю неправильно?
// Deserializes the element in a dictionary.
+(id)deserializeAsDictionary:(CXMLNode*)element {
if([element childCount] == 1) {
CXMLNode* child = [[element children] objectAtIndex:0];
if([child kind] == CXMLTextKind)
{
NSLog(@"The Child Node: %@", [[[element children] objectAtIndex:0] stringValue]);
return [[[element children] objectAtIndex:0] stringValue];
}
}
NSMutableDictionary* d = [NSMutableDictionary dictionary];
for(CXMLNode* child in [element children]) {
id v = [Soap deserialize:child];
if(v == nil) { v = [NSNull null]; }
[d setObject:v forKey:[child name]];
}
return d;
}
NSLog:
2012-04-19 14:13:07.802 Management[3043:10703] Hopefully Child: Allen
2012-04-19 14:13:07.803 Management[3043:10703] Hopefully Child: 1
2012-04-19 14:13:07.804 Management[3043:10703] Hopefully Child: John
2012-04-19 14:13:07.804 Management[3043:10703] Hopefully Child: 2
2012-04-19 14:13:07.805 Management[3043:10703] Hopefully Child: Jackson
2012-04-19 14:13:07.805 Management[3043:10703] Hopefully Child: 3
XML:
<TC diffgr:id="TC1" msdata:rowOrder="0">
<CSHR_POS_NAME>Allen</CSHR_POS_NAME>
<CSHR_NUM>66</CSHR_NUM>
</TC>
<TC diffgr:id="TC2" msdata:rowOrder="1">
<CSHR_POS_NAME>John</CSHR_POS_NAME>
<CSHR_NUM>2</CSHR_NUM>
</TC>
<TC diffgr:id="TC3" msdata:rowOrder="2">
<CSHR_POS_NAME>Jackson</CSHR_POS_NAME>
<CSHR_NUM>3</CSHR_NUM>
</TC>
5 ответов
Решено (поменял мыло.м):
[d setObject:v forKey:[child name]];
NSString* key = [child name];
id check = [d objectForKey:key];
if( check != nil ) {
NSInteger next = 1;
key = [NSString stringWithFormat:@"%@%d", [child name], next];
check = [d objectForKey:key];
while( check != nil ) {
next++;
key = [NSString stringWithFormat:@"%@%d", [child name], next];
check = [d objectForKey:key];
}
[d setObject:v forKey:key];
}
[d setObject:v forKey:[child name]];
Я обнаружил, что вы должны добавить еще блок:
if( check != nil ) {
NSInteger next = 1;
key = [NSString stringWithFormat:@"%@%04d", [child name], next];
check = [d objectForKey:key];
while( check != nil ) {
next++;
key = [NSString stringWithFormat:@"%@%04d", [child name], next];
check = [d objectForKey:key];
}
[d setObject:v forKey:key];
} else {
[d setObject:v forKey:[child name]];
}
//End Extension
В противном случае элементы в 'd' будут перезаписаны, потому что setObject вызывается дважды.
Как только я получу достаточно очков, я пойму, но я заметил, что код начинается и заканчивается
[d setObject:v forKey:[child name]];
и для меня я должен был удалить начальную строку, и это исправило это для меня, поэтому код выглядит так:
// Deserializes the element in a dictionary.
+(id)deserializeAsDictionary:(CXMLNode*)element {
if([element childCount] == 1) {
CXMLNode* child = [[element children] objectAtIndex:0];
if([child kind] == CXMLTextKind) {
return [[[element children] objectAtIndex:0] stringValue];
}
}
NSMutableDictionary* d = [NSMutableDictionary dictionary];
for(CXMLNode* child in [element children]) {
id v = [Soap deserialize:child];
if(v == nil) { v = [NSNull null]; }
//[d setObject:v forKey:[child name]]; //seems to be duped (maybe my bad)
//Extended by iDev on Stackru
//http://stackru.com/questions/10235496/sudzc-deserializeasdictionary-over-written-dictionary/10358458#10358458
NSString* key = [child name];
id check = [d objectForKey:key];
if( check != nil ) {
NSInteger next = 1;
key = [NSString stringWithFormat:@"%@%04d", [child name], next];
check = [d objectForKey:key];
while( check != nil ) {
next++;
key = [NSString stringWithFormat:@"%@%04d", [child name], next];
check = [d objectForKey:key];
}
[d setObject:v forKey:key];
}
[d setObject:v forKey:[child name]];
//End Extension
}
return d;
}
Я не уверен, как вы применили свое исправление, заменяете ли вы весь код в deserializeAsDictionary или добавляете его в конец кода?
вижу, что есть цикл, где строка кода
[d setObject:v forKey:[child name]];
найдено, так что я предполагаю, что вы просто расширили это, чтобы вместо закрытия цикла for вы просто расширяли его здесь, верно?
У меня были проблемы с приведенным выше кодом - он каждый раз перезаписывал первую запись - т.е. я получал список из 4 элементов, а первый и четвертый дублировались.
После долгих изнурительных шагов по коду (люблю рекурсивный код НЕ), я обнаружил, что, как мне кажется, проблема;
Мой код выглядит следующим образом:
if( check != nil ) {
NSInteger next = 1;
key = [NSString stringWithFormat:@"%@%04d", [child name], next];
check = [d objectForKey:key];
while( check != nil ) {
next++;
key = [NSString stringWithFormat:@"%@%04d", [child name], next];
check = [d objectForKey:key];
}
[d setObject:v forKey:key];
}
else
{
[d setObject:v forKey:[child name]];
}