0

我正在制作一个应用程序,我使用 TouchXML 来解析包含机场航班信息的 XML。

XML 如下所示:

<?xml version="1.0" encoding="iso-8859-1"?>
<airport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://flydata.avinor.no/XmlFeed.xsd" name="OSL">
    <flights lastUpdate="2010-10-03T12:29:43">
        <flight uniqueID="1273306">
            <airline>DY</airline>
            <flight_id>DY246</flight_id>
            <dom_int>D</dom_int>
            <schedule_time>2010-10-03T10:45:00</schedule_time>
            <arr_dep>D</arr_dep>
            <airport>TOS</airport>
            <check_in>D</check_in>
            <gate>18</gate>
            <status code="D" time="2010-10-03T10:42:00"/>
        </flight>
        <flight uniqueID="1273799">
            <airline>SK</airline>
            <flight_id>SK263</flight_id>
            <dom_int>D</dom_int>
            <schedule_time>2010-10-03T10:50:00</schedule_time>
            <arr_dep>D</arr_dep>
            <airport>BGO</airport>
            <check_in>EF</check_in>
            <gate>23</gate>
        </flight>
    </flights>
</airport>

TouchXML 文档告诉我如何获取属性,这适用于flights'lastUpdate属性,但不适用于status'codetime属性。

此外,并非所有flightXML 条目都包含该status元素,但我正在对此进行检查。

目前,我拥有的代码如下:

-(void)grabXML {
    flightEntries = [[NSMutableArray alloc] init];

    NSURL *url = [NSURL URLWithString:@"http://flydata.avinor.no/XmlFeed.asp?TimeFrom=0&TimeTo=2&airport=OSL&direction=D"];

    CXMLDocument *xmlParser = [[[CXMLDocument alloc] initWithContentsOfURL:url options:0 error:nil] autorelease];

    NSArray *resultNodes = NULL;

    resultNodes = [xmlParser nodesForXPath:@"//flight" error:nil];

    for (CXMLElement *resultElement in resultNodes) {
        NSMutableDictionary *flightItem = [[NSMutableDictionary alloc] init];

        int counter;

        for (counter = 0; counter < [resultElement childCount]; counter++) {
            [flightItem setObject:[[resultElement childAtIndex:counter] stringValue] forKey:[[resultElement childAtIndex:counter] name]];

            // Check if the node has the <status> element
            if ([[[resultElement childAtIndex:counter] name] isEqualToString:@"status"]) {
                // Fetch the code and time attribute here
            }
        }

        // This gives me <flight uniqueID="*">
        [flightItem setObject:[[resultElement attributeForName:@"uniqueID"] stringValue] forKey:@"uniqueID"];

        [flightEntries addObject:[flightItem copy]];
    }
}

该文档没有说明如何解析多个属性,所以我希望有人知道如何去做?

4

1 回答 1

2

首先,我不得不说您的 XML 将很难使用,因为您正试图为列表中的每个项目使用特定的标记。例如:

            <airline>DY</airline>
            <flight_id>DY246</flight_id>
            <dom_int>D</dom_int>
            <schedule_time>2010-10-03T10:45:00</schedule_time>
            <arr_dep>D</arr_dep>
            <airport>TOS</airport>
            <check_in>D</check_in>
            <gate>18</gate>

名为 的标签没有意​​义,因为 XML 旨在描述您的数据,而不是定义它。如果您有一个名为 item 的实体,您可能应该将其命名为 item 并使 XML 看起来像这样:

 <level1_items>
    <level1_item>
      <item index="1">text</item_1>
      <item index="2">text</item_2>
    </level1_item>
    <level1_item>
      <item index="1">some text</item_1>
      <item index="2">some more text</item_2>
  </level1_items>

每个项目都有一个索引。就此而言,您可以将文档加载到您的 TouchXML CXMLDocument 中,然后使用 XPath 获取您需要的节点,并假设它们的顺序正确,而忽略我指定的 index= 参数。

下一个问题是,将 XML 转换为 NSDictioanry 或 NSArray 的字典是一项相当复杂的任务,而且您获得的东西不值得付出努力。只需将您的 XML 加载到 CXMLDocument 中,然后开始使用 XPath 获取节点。像这样的东西:

CXMLDocument *doc = [[CXMLDocument alloc] initWithXMLString:xmlString options:0 error:nil];

// Returns all 'level1_item' nodes in an array    
NSArray *nodes = [[doc rootElement] nodesForXPath:@"//response/level1_items/level1_item" error:nil];

for (CXMLNode *itemNode in nodes)
{
    for (CXMLNode *childNode in [itemNode children])
    {
        NSString *nodeName = [childNode name]; // should contain item_1 in first iteration
        NSString *nodeValue = [childNode stringValue]; // should contain 'text' in first iteration
        // Do something with the node data.

    }
}

建议尝试以这种方式使用 XML,如果遇到问题,请返回此处并提出具体问题。

希望有帮助。

PK

于 2010-10-03T12:55:27.400 回答