0

私の質問は、予測可能な要素名を持つ不明な数の 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>

重要な部分は、それらの<sky_condition>要素とその属性です。

天候が変化すると、<sky_condition>要素の数が変化します。数は 1 つである場合もあれば、多数である場合もあります。

最終的には、反復順にすべてを表示します。つまり、最初の<sky_condition>要素が最も重要であり、その後に次の要素が続きます。

メソッドを使用traverseElementして XML を反復処理しています。たくさんの<sky_condition>要素の属性を取得し、表示用に保存する必要があります。

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));
}

要素から属性値を抽出し、<sky_condition>それらを配列 (配列?) に格納する必要があることはわかっていますが、これを実現するために記述する必要がある条件について理解できません。

どんな助けやヒントも大歓迎です。

4

1 に答える 1

0

必要な属性を格納するいくつかの 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));
}
于 2014-08-19T18:43:56.763 に答える