我的问题是:如何使用可预测的元素名称提取未知数量的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>
元素的数量会发生变化。可能只有一个,也有多个。
我最终会按迭代顺序显示它们;这是第一个<sky_condition>
元素是最重要的元素,其次是下一个元素。
我使用traverseElement
方法迭代XML。我需要获取有多少<sky_condition>
个元素的属性并存储它们以供显示。
这是traverseElement
方法实现。我传递的参数metarElement代表上面粘贴的XML。
- (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>
元素中提取属性值并将它们存储在一个数组中(数组?),但是我无法理解我需要编写的条件来完成这个。
非常感谢任何帮助或提示。
答案 0 :(得分: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));
}