Pregunta

¿Alguien tiene alguna idea de cómo analizar el siguiente xml utilizando la clase NSXMLParser del modelo controlado por eventos?

<Node>
  <name> Main </name>
  <Node>
    <name> Child 1 </name>
  </Node>

  <Node>
    <name> Child 2 </name>
  </Node>
</Node>

Quiero recopilar los tres nombres de este archivo xml, ¿es posible o tengo que cambiar al análisis basado en árbol?

¿Fue útil?

Solución

Este es un problema común en los programas de análisis como éste, de "tipo SAX", donde usted tiene que mantener un registro manual de la corriente profundidad del árbol XML que se encuentra. El problema, como siempre, es que la carga de la árbol entero en una estructura DOM en la memoria puede ser imposible, dependiendo del tamaño de los datos que desea manipular.

El siguiente código muestra una clase que hace este trabajo:

#import <Foundation/Foundation.h>

@interface Test : NSObject <NSXMLParserDelegate> 
{
@private
    NSXMLParser *xmlParser;
    NSInteger depth;
    NSMutableString *currentName;
    NSString *currentElement;
}

- (void)start;

@end

Esta es la aplicación:

#import "Test.h"

@interface Test ()
- (void)showCurrentDepth;
@end


@implementation Test

- (void)dealloc
{
    [currentElement release];
    [currentName release];
    [xmlParser release];
    [super dealloc];
}

- (void)start
{
    NSString *xml = @"<?xml version=\"1.0\" encoding=\"UTF-8\" ?><Node><name>Main</name><Node><name>Child 1</name></Node><Node><name>Child 2</name></Node></Node>";
    xmlParser = [[NSXMLParser alloc] initWithData:[xml dataUsingEncoding:NSUTF8StringEncoding]];
    [xmlParser setDelegate:self];
    [xmlParser setShouldProcessNamespaces:NO];
    [xmlParser setShouldReportNamespacePrefixes:NO];
    [xmlParser setShouldResolveExternalEntities:NO];
    [xmlParser parse];

}

#pragma mark -
#pragma mark NSXMLParserDelegate methods

- (void)parserDidStartDocument:(NSXMLParser *)parser 
{
    NSLog(@"Document started", nil);
    depth = 0;
    currentElement = nil;
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError 
{
    NSLog(@"Error: %@", [parseError localizedDescription]);
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI 
 qualifiedName:(NSString *)qName 
    attributes:(NSDictionary *)attributeDict
{
    [currentElement release];
    currentElement = [elementName copy];

    if ([currentElement isEqualToString:@"Node"])
    {
        ++depth;
        [self showCurrentDepth];
    }
    else if ([currentElement isEqualToString:@"name"])
    {
        [currentName release];
        currentName = [[NSMutableString alloc] init];
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI 
 qualifiedName:(NSString *)qName
{

    if ([elementName isEqualToString:@"Node"]) 
    {
        --depth;
        [self showCurrentDepth];
    }
    else if ([elementName isEqualToString:@"name"])
    {
        if (depth == 1)
        {
            NSLog(@"Outer name tag: %@", currentName);
        }
        else 
        {
            NSLog(@"Inner name tag: %@", currentName);
        }
    }
}        

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if ([currentElement isEqualToString:@"name"]) 
    {
        [currentName appendString:string];
    } 
}

- (void)parserDidEndDocument:(NSXMLParser *)parser 
{
    NSLog(@"Document finished", nil);
}

#pragma mark -
#pragma mark Private methods

- (void)showCurrentDepth
{
    NSLog(@"Current depth: %d", depth);
}

@end

Este es el resultado de ejecutar una herramienta de línea de comandos que desencadena el método de "arranque" de arriba:

Document started
Current depth: 1
Outer name tag: Main
Current depth: 2
Inner name tag: Child 1
Current depth: 1
Current depth: 2
Inner name tag: Child 2
Current depth: 1
Current depth: 0
Document finished

Otros consejos

- (NSInteger)columnNumber

le da el nivel de anidamiento de NSXMLParser

Una forma muy fácil de resolverlo que la respuesta aceptada, para los archivos XML cortos:

ejemplo XML:

<cotacoes>
    <bovespa>
            <cotacao>50058</cotacao>
            <variacao>-0.16</variacao>
    </bovespa>
    <dolar>
            <cotacao>3.4610</cotacao>
            <variacao>+0.29</variacao>
    </dolar>
    <euro>
            <cotacao>3.7673</cotacao>
            <variacao>-0.25</variacao>
    </euro>
    <atualizacao>04/08/15 - 18:14</atualizacao>
</cotacoes>

Implementar un contador:

@implementation className{
    int parserCounter;
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    parserCounter++;

    NSLog(@"%d: %@",contadorParser,string);

    if (parserCounter == 3) doAnythingFor3;
    if (parserCounter == 5) doAnythingFor5;
    if (parserCounter == 9) doAnythingFor9;
    if (parserCounter == 11) doAnythingFor11;
    if (parserCounter == 15) doAnythingFor15;
    if (parserCounter == 17) doAnythingFor17;
    if (parserCounter == 20) doAnythingFor20;

}

¿Cómo sabré número bruja es nodo de bruja? Al ver el registro. Será algo como:

2015-08-04 23:36:08.070 Tesouro Direto[7252:1554402] 1:     
2015-08-04 23:36:08.070 Tesouro Direto[7252:1554402] 2:     
2015-08-04 23:36:08.071 Tesouro Direto[7252:1554402] 3:     50058
2015-08-04 23:36:08.105 Tesouro Direto[7252:1554402] 4:     
2015-08-04 23:36:08.105 Tesouro Direto[7252:1554402] 5:     -0.16
2015-08-04 23:36:08.131 Tesouro Direto[7252:1554402] 6:     
2015-08-04 23:36:08.132 Tesouro Direto[7252:1554402] 7:     
2015-08-04 23:36:08.132 Tesouro Direto[7252:1554402] 8:     
2015-08-04 23:36:08.132 Tesouro Direto[7252:1554402] 9:     3.4610
2015-08-04 23:36:08.156 Tesouro Direto[7252:1554402] 10:    
2015-08-04 23:36:08.156 Tesouro Direto[7252:1554402] 11:    +0.29   
2015-08-04 23:36:08.180 Tesouro Direto[7252:1554402] 12:    
2015-08-04 23:36:08.180 Tesouro Direto[7252:1554402] 13:    
2015-08-04 23:36:08.180 Tesouro Direto[7252:1554402] 14:    
2015-08-04 23:36:08.180 Tesouro Direto[7252:1554402] 15:    3.7673
2015-08-04 23:36:08.203 Tesouro Direto[7252:1554402] 16:    
2015-08-04 23:36:08.203 Tesouro Direto[7252:1554402] 17:    -0.25
2015-08-04 23:36:08.226 Tesouro Direto[7252:1554402] 18:    
2015-08-04 23:36:08.227 Tesouro Direto[7252:1554402] 19:    
2015-08-04 23:36:08.227 Tesouro Direto[7252:1554402] 20:    04/08/15   - 18:14
2015-08-04 23:36:08.227 Tesouro Direto[7252:1554402] 21: 

El registro le mostrará el número de brujas es cada nodo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top