【问题标题】:Accessing child in XML?访问 XML 中的子项?
【发布时间】:2010-12-11 05:45:48
【问题描述】:

我仍在忙于解析 XML 文件。目前我正在使用 TBXML 从 XML 文件中获取信息。

这是我从不同的 XML 文件中获取一些数据的方法:

TBXML        *XML = [[TBXML tbxmlWithURL:[NSURL URLWithString:locationString]] retain];
TBXMLElement *rootXML = XML.rootXMLElement;
TBXMLElement *e = [TBXML childElementNamed:@"Result" parentElement:rootXML];
TBXMLElement *WOEID = [TBXML childElementNamed:@"woeid" parentElement:e];
NSString     *woeid = [TBXML textForElement:WOEID];

没问题。

但是,现在我想从这个示例 Yahoo RSS XML 文件中获取温度。

http://weather.yahooapis.com/forecastrss?w=12700023

我不知道如何访问包含天气的行。如何使用 TBXML 做到这一点?

谢谢!

【问题讨论】:

    标签: iphone objective-c xml


    【解决方案1】:

    由于 TBXML 仅允许您访问子项,因此您必须遍历树才能找到所需的元素,基本上就像您在示例代码中所做的那样。一般来说,您需要循环,以防有多个具有给定节点名称的子节点。如果只需要第一个,可以使用 if-else 语句代替循环。

    TBXML        *XML = [[TBXML tbxmlWithURL:[NSURL URLWithString:locationString]] retain];
    TBXMLElement *rss = XML.rootXMLElement,
                 *channel,
                 *units,
                 *item,
                 *condition;
    NSString     *temperatureUnits,
                 *temperature;
    
    for (channel = [TBXML childElementNamed:@"channel" parentElement:rss];
         channel;
         channel = [TBXML nextSiblingNamed:@"channel" searchFromElement:channel])
    {
        for (units = [TBXML childElementNamed:@"units" parentElement:channel];
             units;
             units = [TBXML nextSiblingNamed:@"units" searchFromElement:units]) 
        {
            if ((temperatureUnits = [TBXML valueOfAttributeNamed:@"temperature" forElement:units])) {
                [temperatureUnits retain];
                break;
            }
        }
        for (item = [TBXML childElementNamed:@"item" parentElement:channel];
             item;
             item = [TBXML nextSiblingNamed:@"item" searchFromElement:item]) 
        {
            for (condition = [TBXML childElementNamed:@"yweather:condition" parentElement:item];
                condition;
                condition = [TBXML nextSiblingNamed:@"yweather:condition" searchFromElement:condition])
            {
                temperature = [TBXML valueOfAttributeNamed:@"temp" forElement:condition];
                // do something with the temperature
            }
        }
        [temperatureUnits release];
        temperatureUnits = nil;
    }
    

    如果您不想在循环中处理温度,请将它们添加到某种集合(可能是 NSMutableArray)中。

    【讨论】:

    • 它可以工作,尽管在调用[temperatureUnits release]; 时它会使应用程序崩溃。也许它是零。我开始认为使用 TBXML 是个坏主意,我应该坚持使用默认的 NSXML 吗?
    • 其实是因为temperatureUnits不是 nil(nil忽略消息)。已经很晚了,我把自己弄糊涂了,以为temperatureUnits 被循环了。 temperatureUnitsretain/release 严格来说并不是必需的。最初,我正朝着不同的方向前进。通过在发布后将 temperatureUnits 设置为 nil(如更新的答案)或删除 retainrelease 来修复它。
    • 我会选择NSXML,因为它支持XPath and XQuery,因此您可以或多或少地直接访问您想要的节点。
    猜你喜欢
    • 1970-01-01
    • 2011-01-23
    • 2017-10-10
    • 2010-12-05
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 2014-11-04
    • 1970-01-01
    相关资源
    最近更新 更多