Analisando elementos aninhados múltiplos e multinistrados com touchxml
Pergunta
Eu tenho um XML com a seguinte estrutura e estou tentando criar meu objeto modelo a partir disso. Alguém pode me ajudar a encontrar uma maneira de obter esses objetos do XML usando o Touchxml, NSMutableArray e NSMutabledictionAy.
<?xml version="1.0" encoding="utf-8"?>
<response>
<level1_items>
<level1_item>
<item_1>text</item_1>
<item_2>text</item_2>
</level1_item>
<level1_item>
<item_1>some text</item_1>
<item_2>some more text</item_2>
</level1_items>
<items>
<item>
<child_items>
<child_item>
<leaf1>node text</leaf1>
<leaf2>leaf text</leaf2>
<leaf3>some text</leaf3>
</child_item>
<child_item>
<leaf1>text</leaf1>
<leaf2>leaf text</leaf2>
<leaf3>more text</leaf3>
</child_item>
</child_items>
</item>
<item>
<child_items>
<child_item>
<leaf1>node text</leaf1>
<leaf2>leaf text</leaf2>
<leaf3>some text</leaf3>
</child_item>
<child_item>
<leaf1>text</leaf1>
<leaf2>leaf text</leaf2>
<leaf3>more text</leaf3>
</child_item>
</child_items>
</item>
</items>
</response>
Eu preciso analisar o <response>
e seus filhos.
Solução
Primeiro, devo dizer que seu XML será difícil de trabalhar, porque você está tentando usar uma tag específica para cada item em uma lista. Por exemplo:
<level1_items>
<level1_item>
<item_1>text</item_1>
<item_2>text</item_2>
</level1_item>
<level1_item>
<item_1>some text</item_1>
<item_2>some more text</item_2>
</level1_items>
as tags nomeadasu003Citem_ 1> , Assim,u003Citem_ 2> Não faça sentido, pois o XML visa descrever seus dados, não defini -los. Se você tem uma entidade chamada um item, provavelmente deve chamá -lo item E faça o XML parecer assim:
<level1_items>
<level1_item>
<item index="1">text</item>
<item index="2">text</item>
</level1_item>
<level1_item>
<item index="1">some text</item>
<item index="2">some more text</item>
</level1_items>
Onde cada um item tem um índice. Por esse motivo, você pode apenas carregar o documento no seu CXMLDocument e pegar os nós que você precisa com o XPath e assumir que eles estão na ordem correta ignorando o parâmetro index = especifiquei.
A próxima edição é que a conversão de XML em uma NSDictioanry ou NSarray of Dicionies é uma tarefa bastante envolvida e o que você ganha não vale o esforço. Basta carregar seu XML em um cxmldocument e depois começar a obter nós usando o XPath. Algo assim:
CXMLDocument *doc = [[CXMLDocument alloc] initWithXMLString:xmlString options:0 error:nil];
// Returns all 'level1_item' nodes in an array
NSArray *nodes = [[doc rootElement] nodesForXPath:@"//response/level1_items/level1_item" error:nil];
for (CXMLNode *itemNode in nodes)
{
for (CXMLNode *childNode in [itemNode children])
{
NSString *nodeName = [childNode name]; // should contain item_1 in first iteration
NSString *nodeValue = [childNode stringValue]; // should contain 'text' in first iteration
// Do something with the node data.
}
}
Sugiro tentar usar o XML dessa maneira e depois volte aqui e faça perguntas específicas se tiver problemas.
Outras dicas
-(NSMutableArray *)parseNodeFromXML:(NSString *)strXML readForNode:(NSString *)strReadValue
{
NSError *theError = NULL;
CXMLDocument *theXMLDocument = [[CXMLDocument alloc] initWithXMLString:strXML options:0 error:&theError] ;
NSMutableArray *arrReturn = [[NSMutableArray alloc] init];
NSArray *nodes = [[theXMLDocument rootElement] nodesForXPath:strReadValue error:nil];
for (CXMLNode *itemNode in nodes)
{
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
// PROCESS FOR READ ELEMENT ATTRIBUTES IN CURRENT NODE -------------------------
if([itemNode isMemberOfClass:[CXMLElement class]]){
CXMLElement *elements=(CXMLElement*)itemNode;
NSArray *arAttr=[elements attributes];
for (int i=0; i<[arAttr count]; i++) {
if([[arAttr objectAtIndex:i] name] && [[arAttr objectAtIndex:i] stringValue]){
[dic setValue:[[arAttr objectAtIndex:i] stringValue] forKey:[[arAttr objectAtIndex:i] name]];
}
}
}
// PROCESS FOR READ CHILD NODE IN CURRENT NODE -------------------------
for (CXMLNode *childNode in [itemNode children])
{
// NSLog(@"count -- %d --- %@",[childNode childCount],[childNode children]);
// IF ANY CHILD NODE HAVE MULTIPLE CHILDRENS THEN DO THIS....-
if ([childNode childCount] > 1)
{
NSMutableDictionary *dicChild = [[NSMutableDictionary alloc] init];
for (CXMLNode *ChildItemNode in [childNode children])
{
[dicChild setValue:[ChildItemNode stringValue] forKey:[ChildItemNode name]];
}
[dic setValue:dicChild forKey:[childNode name]];
}else
{
[dic setValue:[childNode stringValue] forKey:[childNode name]];
}
}
[arrReturn addObject:dic];
}
// NSLog(@"%@",arrReturn);
return arrReturn;
}
may this help for multiple get child