-1

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

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

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

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

我的老板告诉我将代码更改为使用 NSXML 解析器而不是 TBXML 解析器。但是我看过教程,但我并没有简单地理解它。

有人可以帮我把我的 TBXML 代码块翻译成 NSXML 代码吗?顺便说一句,“对象”是一棵树,详细信息是该树的特定信息,如湿度、分类、高度、温度等。

这是 XML url 的链接:(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,找到“dato”的每个孩子,然后将“>”和“<”中的内容保存为字符串值,这样我以后可以将它放入一个对象数组中,我必须将数据放入我的单元格中。如您所见,我使用“diametroElementNumber”执行了一些 if-else 语句,这是因为相应的 ThumbImageDiametro(相应单元格中的图像)将根据“diametroElementNumber”值发生变化。(树直径大小)。我使用了一个简单的整数转换。

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

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

}

最后是表格视图的一些通用/默认方法:

//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&TBXML.m文件进行解析,并使用 NSXML 解析器来执行上述相同操作。

基本上我只想得到翻译后的代码。

先感谢您

4

1 回答 1

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:

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

  1. didStartElement:中,如果元素是“dato”,那么您可能想要分配/初始化您的自定义Tree类并将其存储到实例或属性中currentTree
  2. foundCharacters:中,您可能将传入的字符存储到实例或属性中currentString
- (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];
    }
  1. didEndElement:中,如果元素是“taxonomia”或“plantado”或您想要存储到您的类的任何其他字段,那么您将 分配currentString给该类成员。您还可以使用 KVC(假设您的类符合并完全匹配 xml 字段)执行以下操作:

    [self.currentTree setValue:self.currentString forKey:elementName];

这将为您省去制作几个重复语句的麻烦,例如

if ([elementName isEqualToString:@"taxonomia"]) {...}

您也需要设置currentStringnil此处,这样您就不会最终创建一个长的可变字符串!此外,如果didEndElementelementName 中的“dato”是“dato”,那么您知道该对象已完成,因此您可以将其添加到集合中或在那里执行其他操作。

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

这些是基础。NSXMLParser您可以使用类和委托协议的更多功能进行扩展。你的 tableview 只需要一些小的调整来处理你的Tree类对象,这将是非常值得的。

于 2014-09-24T21:54:14.257 回答