要解析的奇怪XML文档

时间:2012-10-30 09:02:36

标签: iphone ios xcode xml-parsing

我正在尝试在IOS中解析这个XML代码:

<?xml version="1.0" encoding="ISO-8859-1"?>
<ofertas>
    <oferta>
        <id>138</id>
        <connector/>
        <codigo>PARMAD</codigo>
        <titulo><![CDATA[Madrid, BordÈus e Paris]]></titulo>

        <descricao><![CDATA[ 7 dias c/ Pequeno AlmoÁo - Apenas Circuito Terrestre - Alojamento e Pequeno-AlmoÁo ; 7 dias c/ Pequeno AlmoÁo - SaÌda com voo de Lisboa - Alojamento e Pequeno-AlmoÁo ; 7 dias c/ Pequeno AlmoÁo - SaÌda com voo do Porto - Alojamento e Pequeno-AlmoÁo ; 7 dias c/ Pequeno AlmoÁo - SaÌda com voo de Faro - Alojamento e Pequeno-AlmoÁo]]></descricao>
        <datas><![CDATA[Consultar programa]]></datas>
        <data1>2012-07-31</data1>
        <data2>2013-03-23</data2>

        <categoria>Europa</categoria>
        <subcategoria>Circuitos Europa</subcategoria>
        <zona>Turistica</zona>
        <tipo>Circuitos Europa</tipo>

        <valor>575</valor>
        <dias>6</dias>

        <imagem>http://www.optitravel.net/optitravel/www/media/custom/cli_202/media/PKT_138_1343738358.jpg</imagem>

        <link/>

    </oferta>

    <oferta>
        <id>140</id>
        <connector/>
        <codigo>PARPRG</codigo>
        <titulo><![CDATA[Paris, Frankfurt e Praga]]></titulo>

        <descricao><![CDATA[ 7 dias c/ Pequeno AlmoÁo - Apenas Circuito Terrestre - Alojamento e Pequeno-AlmoÁo ; 7 dias c/ Pequeno AlmoÁo - SaÌda com voo de Lisboa - Alojamento e Pequeno-AlmoÁo ; 7 dias c/ Pequeno AlmoÁo - SaÌda com voo do Porto - Alojamento e Pequeno-AlmoÁo ; 7 dias c/ Pequeno AlmoÁo - SaÌda com voo de Faro - Alojamento e Pequeno-AlmoÁo]]></descricao>
        <datas><![CDATA[01/Nov, 08/Nov, 15/Nov, 29/Nov, 13/Dez, 27/Dez, 10/Jan/2013, 24/Jan/2013, 07/Fev/2013, 21/Fev/2013, 07/Mar/2013, 21/Mar/2013]]></datas>
        <data1>2012-08-01</data1>
        <data2>2013-03-21</data2>

我不知道它是解析大文件的最佳选择,但我使用SMXMLDocument来解析这个特定的XML。我遇到的问题是我无法解码这个XML。以下是我正在使用的XML解析器的作者给出的代码示例:

  //REPLACED WITH MY XML DOC
NSString *sampleXML = [[NSBundle mainBundle] pathForResource:@"global" ofType:@"xml"];
NSData *data = [NSData dataWithContentsOfFile:sampleXML];

// create a new SMXMLDocument with the contents of sample.xml
NSError *error;
SMXMLDocument *document = [SMXMLDocument documentWithData:data error:&error];

// check for errors
if (error) {
    NSLog(@"Error while parsing the document: %@", error);
    return;
}

// demonstrate -description of document/element classes
NSLog(@"Document:\n %@", document);

// Pull out the <books> node
SMXMLElement *books = [document.root childNamed:@"????"];

// Look through <books> children of type <book>
for (SMXMLElement *book in [books childrenNamed:@"????"]) {

    // demonstrate common cases of extracting XML data
    NSString *isbn = [book attributeNamed:@"id"]; // XML attribute
    NSString *title = [book valueWithPath:@"titulo"]; // child node value


    // show off some KVC magic
    NSArray *authors = [[book childNamed:@"authors"].children valueForKey:@"value"];

    NSLog(@"Found a book!\n ISBN: %@ \n Title: %@ \n Price: %f \n", isbn, title, price);
}

如果有更好的XML解析器来解析此文档,请提供建议。

2 个答案:

答案 0 :(得分:1)

您可以选择TBXML Parser。它旨在提供最快的XML解析,同时利用最少的资源。

答案 1 :(得分:1)

正如@AppleDelegate所说,我也使用TBXML Parser。这是我将使用的代码。在使用之前,您需要导入TBXML+HTTP.h。只需在您想要的地方调用[self getXML],代码将完成其余的工作。

首先获取xml:

-(void)getXML {

    NSLog(@"Getting XML");

    // Create a success block to be called when the async request completes
    TBXMLSuccessBlock successBlock = ^(TBXML *tbxmlDocument) {

        // If TBXML found a root node, process element and iterate all children
        if (tbxmlDocument.rootXMLElement)
            [self traverseElement:tbxmlDocument.rootXMLElement];

    };

    // Create a failure block that gets called if something goes wrong
    TBXMLFailureBlock failureBlock = ^(TBXML *tbxmlDocument, NSError * error) {
        NSLog(@"Error! %@ %@", [error localizedDescription], [error userInfo]);
    };

    // Initialize TBXML with the URL of an XML doc. TBXML asynchronously loads and parses the file.
    TBXML *tbxml = [[TBXML alloc] initWithURL: [NSURL URLWithString:@"File.xml"] 
                                      success: successBlock 
                                      failure: failureBlock];
}

然后阅读文件:

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

    TBXMLElement *oferta = element->firstChild;

    do {

        // Obtain first attribute from element
        TBXMLElement *element = oferta->firstChild;
        NSString *ofertaId = [NSString stringWithString: [TBXML textForElement:element]];
        NSLog(@"%@", ofertaId);

        // Obtain the next element
        element = element->nextSibling;
        // Nothing to do (<connector/>)

        // Obtain the next element
        element = element->nextSibling;
        NSString *codigo = [TBXML textForElement:element];
        NSLog(@"%@", codigo);

        // Obtain the next element
        element = element->nextSibling;
        NSString *titulo = [TBXML textForElement:element];
        NSLog(@"%@", titulo);

        // Obtain the next element
        element = element->nextSibling;
        NSString *descricao = [TBXML textForElement:element];
        NSLog(@"%@", descricao);

        // Obtain the next element
        element = element->nextSibling;
        NSString *datas = [TBXML textForElement:element];
        NSLog(@"%@", datas);

        // Obtain the next element
        element = element->nextSibling;
        NSString *data1 = [TBXML textForElement:element];
        NSLog(@"%@", data1);

        // Obtain the next element
        element = element->nextSibling;
        NSString *data2 = [TBXML textForElement:element];
        NSLog(@"%@", data2);

        // Obtain the next element
        element = element->nextSibling;
        NSString *categoria = [TBXML textForElement:element];
        NSLog(@"%@", categoria);

        // Obtain the next element
        element = element->nextSibling;
        NSString *subcategoria = [TBXML textForElement:element];
        NSLog(@"%@", subcategoria);

        // Obtain the next element
        element = element->nextSibling;
        NSString *zona = [TBXML textForElement:element];
        NSLog(@"%@", zona);

        // Obtain the next element
        element = element->nextSibling;
        NSString *tipo = [TBXML textForElement:element];
        NSLog(@"%@", tipo);

        // Obtain the next element
        element = element->nextSibling;
        NSString *valor = [TBXML textForElement:element];
        NSLog(@"%@", valor);

        // Obtain the next element
        element = element->nextSibling;
        NSString *dias = [TBXML textForElement:element];
        NSLog(@"%@", dias);

        // Obtain the next element
        element = element->nextSibling;
        NSString *imagem = [TBXML textForElement:element];
        NSLog(@"%@", imagem);

        // Obtain the next element
        element = element->nextSibling;
        // Nothing to do (<link/>)

        // Save infos

    } while ((oferta = oferta->nextSibling));

    NSLog(@"Done");
}

我已经测试了代码,它似乎工作正常(运行代码,并检查控制台日志)。您需要做的就是将// Save infos从我的代码更改为您可以保存所有字符串的内容。 do-while将遍历xml中的所有<oferta>元素,并将所需的所有元素保存在单独的字符串中。然后,您可以操纵字符串来存储日期,数字和所有内容。