解析 TouchXML 中的多个属性

发布于 2024-09-25 18:00:00 字数 2962 浏览 6 评论 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 文档告诉我如何获取属性,该属性适用于 flightslastUpdate 属性,但不适用于 statuscodetime 属性。

此外,并非所有 flight XML 条目都包含 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]];
    }
}

文档没有告诉如何解析多个属性,所以我希望有人知道如何做到这一点?

I'm in the making of an application where I'm using TouchXML to parse an XML containing airport flight information.

The XML looks like this:

<?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>

The TouchXML documentation tells me how to fetch attributes, which works for flights's lastUpdate attribute, but not for status's code and time attribute.

In addition, not all flight XML entries contain the status element, but I'm doing a check for this.

Currently, the code I have is the following:

-(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]];
    }
}

The documentation does not tell how to parse multiple attributes, so I was hoping someone had a clue on how to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

合约呢 2024-10-02 18:00:00

首先,我不得不说您的 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 旨在描述您的数据,而不是定义它。如果您有一个称为项目的实体,那么您可能应该将其称为项目,并使 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

First off, I have to say that your XML will be difficult to work with because you are trying to use a specific tag for each item in a list. For example:

            <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>

the tags named , don't make sense as XML is intended to describe your data, not define it. If you have an entity called an item, you should probably just call it item and make the XML look like this:

 <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>

Where each item has an index. For that matter, you could just load the document in your TouchXML CXMLDocument and grab the nodes you need with XPath and assume they're in the correct order ignoring the index= parameter I specified.

The next issue is that converting XML to an NSDictioanry or NSArray of dictionaries is a pretty involved task and what you gain isn't worth the effort. Just load your XML into a CXMLDocument and then start obtaining nodes using XPath. Something like this:

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.

    }
}

suggest trying to use the XML this way and then come back here and ask specific questions if you have problems.

hope that helps.

PK

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文