【问题标题】:Use TBXML to grab an unknown number of elements使用 TBXML 抓取未知数量的元素
【发布时间】:2014-10-11 20:46:34
【问题描述】:

我的问题是:如何提取未知数量的具有可预测元素名称的 XML 元素并获取它们的属性值?

我正在使用 TBXML(目前为止很喜欢)来解析来自国家气象局的气象观测数据。

这是一个 XML 示例(<METAR> 元素是相关部分)

<METAR>
    <raw_text>
        KDEN 181953Z 01006KT 10SM FEW080 SCT110 SCT150 31/06 A3007 RMK AO2 SLP093 OCNL LTGCG DSNT SW VIRGA S-SW CB DSNT SW MOV E T03110061
    </raw_text>
    <station_id>KDEN</station_id>
    <observation_time>2014-08-18T19:53:00Z</observation_time>
    <latitude>39.85</latitude>
    <longitude>-104.65</longitude>
    <temp_c>31.1</temp_c>
    <dewpoint_c>6.1</dewpoint_c>
    <wind_dir_degrees>10</wind_dir_degrees>
    <wind_speed_kt>6</wind_speed_kt>
    <visibility_statute_mi>10.0</visibility_statute_mi>
    <altim_in_hg>30.070866</altim_in_hg>
    <sea_level_pressure_mb>1009.3</sea_level_pressure_mb>
    <quality_control_flags>
        <auto_station>TRUE</auto_station>
    </quality_control_flags>
    <sky_condition sky_cover="FEW" cloud_base_ft_agl="8000"/>
    <sky_condition sky_cover="SCT" cloud_base_ft_agl="11000"/>
    <sky_condition sky_cover="SCT" cloud_base_ft_agl="15000"/>
    <flight_category>VFR</flight_category>
    <metar_type>METAR</metar_type>
    <elevation_m>1640.0</elevation_m>
</METAR>

重要的部分是那些&lt;sky_condition&gt; 元素及其属性。

随着天气的变化,&lt;sky_condition&gt; 元素的数量也会发生变化。可能少则一个,多则多。

我最终会按照迭代的顺序将它们全部展示出来;也就是说,第一个 &lt;sky_condition&gt; 元素是最重要的,其次是下一个,等等。

我正在使用traverseElement 方法来迭代XML。无论有多少 &lt;sky_condition&gt; 元素,我都需要获取它们的属性并将它们存储起来以供显示。

这里是traverseElement 方法的实现。我正在传递表示上面粘贴的 XML 的参数 metaElement。

- (void) traverseElement:(TBXMLElement *)element {

    do {
        // Display the name of the element
        NSLog(@"%@",[TBXML elementName:element]);

        // Obtain first attribute from element
        TBXMLAttribute * attribute = element->firstAttribute;

        while (attribute) {
            // Display name and value of attribute to the log window
            NSLog(@"%@->%@ = %@",  [TBXML elementName:element],
                  [TBXML attributeName:attribute],
                  [TBXML attributeValue:attribute]);

            // Obtain the next attribute
            attribute = attribute->next;
        }

        // if the element has child elements, process them
        if (element->firstChild)
            [self traverseElement:element->firstChild];

        // Obtain next sibling element
    } while ((element = element->nextSibling));
}

我知道我需要从 &lt;sky_condition&gt; 元素中提取属性值并将它们存储在一个数组(数组?)中,但我无法理解我需要编写完成此操作的条件。

任何帮助或提示将不胜感激。

【问题讨论】:

    标签: ios cocoa-touch xml-parsing tbxml


    【解决方案1】:

    我通过创建一些 NSMutableArrays 来存储我需要的属性来实现这一点。在我的@interface:

    @property (nonatomic) BOOL isSkyClear;
    @property (strong, nonatomic) NSMutableArray *fewArray;
    @property (strong, nonatomic) NSMutableArray *sctArray;
    @property (strong, nonatomic) NSMutableArray *bknArray;
    @property (strong, nonatomic) NSMutableArray *ovcArray; 
    

    以及方法实现- (void) traverseElement:(TBXMLElement *)element {

     do {
            // Display the name of the element
            NSLog(@"%@",[TBXML elementName:element]);
    
            // Obtain first attribute from element
            TBXMLAttribute * attribute = element->firstAttribute;
    
            while (attribute) {
                // Display name and value of attribute to the log window
    
                NSLog(@"%@->%@ = %@",  [TBXML elementName:element],
                    [TBXML attributeName:attribute],
                    [TBXML attributeValue:attribute]);
    
                if ([[TBXML attributeValue:attribute] isEqualToString:@"CLR"]) {
                    self.isSkyClear = YES;
    
                } else if ([[TBXML attributeValue:attribute] isEqualToString:@"FEW"]) {
                    attribute = attribute->next;
                    NSString *cloudBase = [TBXML attributeValue:attribute];
                    [self.fewArray addObject:cloudBase];
                    break;
    
                } else if ([[TBXML attributeValue:attribute] isEqualToString:@"SCT"]) {
                    attribute = attribute->next;
                    NSString *cloudBase = [TBXML attributeValue:attribute];
                    [self.sctArray addObject:cloudBase];
                    break;
    
                } else if ([[TBXML attributeValue:attribute] isEqualToString:@"BKN"]) {
                    attribute = attribute->next;
                    NSString *cloudBase = [TBXML attributeValue:attribute];
                    [self.bknArray addObject:cloudBase];
                    break;
    
                } else if ([[TBXML attributeValue:attribute] isEqualToString:@"OVC"]) {
                    attribute = attribute->next;
                    NSString *cloudBase = [TBXML attributeValue:attribute];
                    [self.ovcArray addObject:cloudBase];
                    break;                    
                } 
    
                attribute = attribute->next;   
            }
    
            // Obtain next sibling element
        } while ((element = element->nextSibling));
    }
    

    【讨论】:

      猜你喜欢
      • 2018-10-17
      • 2011-11-16
      • 2014-02-01
      • 2013-07-10
      • 2014-06-03
      • 1970-01-01
      • 2020-12-17
      • 1970-01-01
      • 2019-03-07
      相关资源
      最近更新 更多