将TBXML解析器转换为NSXML解析器

时间:2014-09-24 19:07:20

标签: objective-c xml uitableview nsxmlparser tbxml

我正在为Xcode6中的iOS设备开发一个应用程序(刚刚从xcode5更新),在某些时候用户按下一个按钮然后看到一个tableview,信息很好地合并到每个单元格中,这个信息是相应对象的细节,当他/她按下按钮时,该对象由标识符数值指定。

所以基本上,使用segue方法我捕获用户在前一个视图(SecondViewController.m)中在文本字段中输入的数值,然后有另一个视图,其中只有一个按钮被看到,该数字为'标签。用户按下按钮并弹出一个tableview,显示该对象的详细信息。

从xml URL检索数据(详细信息),使用我的项目将TBXML作为我的解析器,一切正常。

但是最近我在真实设备(iphone5s)上测试了应用程序,当我按下按钮以查看tableview和我的对象详细信息时,它什么也没发生,好像按钮不在那里,至少功能,但在模拟器中工作得很好。

我的老板告诉我更改我的代码以使用NSXML解析器而不是TBXML解析器。但我已经看过教程,但我并不是简单地得到它。

请有人帮我翻译我的TBXML代码块为NSXML代码。 BTW"对象"是一棵树,细节是该树的具体信息,如湿度,分类,高度,温度等。

这是XML网址的链接:http://papvidadigital.com/risi/?nid=83(从对象83获取信息)

是一个非常简单的XML。

这是涉及解析xml的代码。

//XML


//LOADING THE XML FILE
//create link




NSString *buildingURL = [NSString stringWithFormat:@"http://papvidadigital.com/risi/?nid=%@", _passingValueToTable];




NSURL *myUrl = [NSURL URLWithString:buildingURL];

//setting data
NSData *myData = [NSData dataWithContentsOfURL:myUrl];

TBXML *sourceXML = [[TBXML alloc] initWithXMLData:myData error:nil];


//EXTRACT ELEMENTS
TBXMLElement *rootElement = sourceXML.rootXMLElement;

TBXMLElement *datoElement = [TBXML childElementNamed:@"dato" parentElement:rootElement];



//EXTRACT ATTRIBUTES

//EXTRACT element

//NID
//TBXMLElement *nidElement = [TBXML childElementNamed:@"NID" parentElement:datoElement];
//NSString *nidElementString = [TBXML textForElement:nidElement];
//NSLog(@"NID: %@\n", [nidElementString lowercaseString]);

//taxonomia
TBXMLElement *taxonomiaElement = [TBXML childElementNamed:@"taxonomia" parentElement:datoElement];
NSString *taxonomiaElementString = [TBXML textForElement:taxonomiaElement];
NSLog(@"taxonomia: %@\n", [taxonomiaElementString lowercaseString]);



//diametro
TBXMLElement *diametroElement = [TBXML childElementNamed:@"diametro" parentElement:datoElement];

NSString *diametroElementString = [TBXML textForElement:diametroElement];
NSString *diametroElementText = [ NSString stringWithFormat:@"%@ cm", diametroElementString];

    NSLog(@"diametro: %@\n", [diametroElementString lowercaseString]);

//Verificar y validar icono correspondiente
NSString *ThumbImageDiametro;
NSInteger diametroElementNumber = [diametroElementString integerValue];
if(diametroElementNumber >= 30){
    ThumbImageDiametro = @"diametroalto.png";
}else if(diametroElementNumber >= 15 && diametroElementNumber < 30){
    ThumbImageDiametro = @"diametromedio.png";
}else if(diametroElementNumber < 15){
    ThumbImageDiametro = @"diametropequeño.png";
}

抱歉,有些条款是西班牙语。基本上我解析了xml,发现每个孩子都是&#34; dato&#34;然后保存内部&#34;&gt;&#34;和&#34;&lt;&#34;作为一个字符串值所以我以后可以将它放在一个对象数组中我必须将数据放入我的单元格。正如你所看到我用&#34; diametroElementNumber&#34;做了一些if-else语句,这是因为相应的ThumbImageDiametro(相应单元格中的图像)将根据&#34; diametroElementNumber&#34;而变化。值。 (树直径大小)。我使用了一个简单的强制转换为整数。

以下是我的对象数组的一个小例子:

_Description = @[taxonomiaElementString,
                 PlantadoElementString,
                 diametroElementText];

这是我的图像对象数组(每个单元格中的图像):

_Images = @[@"taxonomia.png",
            @"fechadeplantacion.png",
            ThumbImageDiametro];

这是我的对象每个单元格的固定标题数组:

_Title = @[@"Taxonomía",
           @"Año de Plantado",
           @"Diámetro"];

这就是我将数据放入每个单元格的方式:

//Put data into CELLS
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{



    //for cells that have TableCell as identifier
    static NSString *CellIdentifier = @"TableCell";
    Cell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Configure the cell...

    long row = [indexPath row];
    cell.TitleLabel.text = _Title[row];

    cell.DescriptionLabel.text = _Description[row];
    //put corresponding image
    cell.ThumbImage.image = [UIImage imageNamed:_Images[row]];

    [cell setBackgroundColor:[UIColor whiteColor]];

    return cell;

}

最后是tableview的一些通用/默认方法:

//calculates and returns number of sections in tableview controller
- (NSInteger)numberOfSelectionsInTableView:(UITableView *)tableView
{
    return 1; //number of sections
}
//calculates and returns number of rows in the section
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _Title.count;
}

请有人帮助我改变必要的内容,以便停止使用外部TBXML.h&amp;然后使用TBXML.m文件解析,并使用NSXML解析器执行与上述相同的操作。

基本上我只想要翻译代码。

提前谢谢

1 个答案:

答案 0 :(得分:0)

如果您需要将代码转换为NSXML解析器,那么NSXMLParser类和NSXMLParserDelegate协议的文档是您最好的开始。

要将其细分为基础知识,您基本上可以按照以下步骤开始:

  1. 通过将类放入类标题,宣布您的类(可能是视图控制器?)符合NSXMLParserDelegate协议。
  2. 创建NSXMLParser的实例变量(或更好的属性)。您甚至可以直接从URL下拉数据,如下所示:

    self.treeParser = [[NSXMLParser alloc] initWithContentsOfURL:myUrl];

  3. 确保将self设置为委托,以便捕获委托回调。此外,您还可以处理其他功能,例如解析外部实体等。

    self.treeParser.delegate = self; self.treeParser.shouldResolveExternalEntities = YES;

  4. 处理您想要的NSXMLParserDelegate方法,最有可能:

    • parser:didStartElement:...
    • parser:didEndElement:...,`
    • parser:foundCharacters:
    • parser:parseErrorOccurred:
  5. 上面列出的委托方法完成了大部分工作。您可以为当前解析的对象创建实例变量(或属性),并在完成解析时存储它们。构建一致对象(如树数据)时,最好创建自定义类。因此,对于您的示例XML,您可以使用具有taxonomia和plantado等属性的Tree类来存储来自服务的数据。然后,您可以遵循基本的解析模式

    1. didStartElement:中,如果元素是&#34; dato&#34;,那么您希望分配/初始化自定义Tree类并将其存储到实例或属性{{1 }} 也许。
    2. currentTree中,您可以将传入的字符存储到实例或属性foundCharacters:
    3. currentString
      1. - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { if (!self.currentString) { // currentString is an NSMutableString typed property self.currentString = [[NSMutableString alloc] initWithCapacity:50]; } [self.currentString appendString:string]; } 中,如果元素是&#34;分类法&#34;或&#34; plantado&#34;或者您想要存储到班级的任何其他字段,然后将didEndElement:分配给该班级成员。您还可以使用KVC(假设您的类符合并完全匹配xml字段)来执行以下操作:

        currentString

      2. 这样可以省去制作像

        这样的重复语句的麻烦
        [self.currentTree setValue:self.currentString forKey:elementName];

        您还希望在此设置if ([elementName isEqualToString:@"taxonomia"]) {...} currentString,这样您就不会创建一个长长的可变字符串!此外,如果在nil中elementName是&#34; dato&#34;,那么您知道该对象已完成,因此您可以将其添加到集合或在那里执行其他操作。

        当然,您应该实施didEndElement来处理您可能遇到的任何错误。

        这些是基础知识。您可以使用parseErrorOccurred:类的更多功能进行扩展,并委派协议。您的tableview只需要进行一些小的调整即可使用NSXMLParser类对象,这非常值得。