2009-11-19 31 views
0

我有一个带有以下结构的XML,我试图从中创建我的模型对象。有人可以帮助我找到一种方法,使用TouchXML,NSMutableArray和NSMutableDictionay从XML中获取这些对象。使用TouchXML解析多个和多级嵌套元素

<?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> 

我需要解析<response>及其子。

回答

6

首先,我不得不说你的XML很难处理,因为你正在尝试为列表中的每个项目使用一个特定的标签。例如:

<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> 

命名< ITEM_ 1 >标签,< ITEM_ 2 >如XML是用来描述你的数据,而不是定义它没有任何意义。如果你有一个实体,称为一个项目,你应该叫它项目,使XML是这样的:

<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> 

如果每个项目有一个索引。对于这个问题,您可以将文档加载到TouchXML CXMLDocument中,并使用XPath获取所需的节点,并假定它们按照正确的顺序忽略我指定的index =参数。

下一个问题是,将XML转换为NSDictioanry或NSArray的字典是一项相当复杂的任务,您所获得的不值得付出努力。只需将您的XML加载到CXMLDocument中,然后使用XPath开始获取节点。这样的事情:

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. 

    } 
} 

我建议尝试使用XML这种方式,然后回来这里,并问如果你有问题的具体问题。

0
-(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