2012-07-04 13 views
15

Hola, estoy creando una aplicación que tiene que imprimir un valor en la etiqueta desde un archivo xml en el servidor. Intenté leer parte de la documentación en la búsqueda de google ... pero no puedo encontrarla. . ¿Alguien sabe tutorial simple o cualquier código de muestra que se utiliza para integrar el análisis XML en mi aplicación.Análisis Xml en el tutorial de iOS

+0

http://developer.apple.com/library/ios/#samplecode/XMLPerformance/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008094. Espero que este código de ejemplo lo ayude, – Neo

Respuesta

5

Use el analizador TBXml .. Esa es la manera más fácil y también menos tiempo para analizar un valor ... Puedo descargar el proyecto TBXMLDemo en github e imprimir eso en lugar de etiqueta puede usar la celda de vista de tabla y hacerla seleccionar como null.Así que parece una etiqueta similar. Si necesita más detalles coménteme, .. lo ayudaré ...

19

Puede analizar XML con el siguiente código. Pero debes crear clases que puedes encontrar a continuación.

NSURL *URL = [[NSURL alloc] initWithString:@"http:/sites.google.com/site/iphonesdktutorials/xml/Books.xml"]; 
    NSString *xmlString = [[NSString alloc] initWithContentsOfURL:URL encoding:NSUTF8StringEncoding error:NULL]; 
    NSLog(@"string: %@", xmlString); 
    NSDictionary *xmlDoc = [NSDictionary dictionaryWithXMLString:xmlString]; 
    NSLog(@"dictionary: %@", xmlDoc); 

lo necesario para crear estas clases de XML analizar con el nombre de XMLParser.

XMLParser.h

// 
// XMLParser.h 
// 
// 
// Copyright 2016 Darshan kunjadiya. All rights reserved. 


#import <Foundation/Foundation.h> 
#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wobjc-missing-property-synthesis" 


typedef NS_ENUM(NSInteger, XMLDictionaryAttributesMode) 
{ 
    XMLDictionaryAttributesModePrefixed = 0, //default 
    XMLDictionaryAttributesModeDictionary, 
    XMLDictionaryAttributesModeUnprefixed, 
    XMLDictionaryAttributesModeDiscard 
}; 


typedef NS_ENUM(NSInteger, XMLDictionaryNodeNameMode) 
{ 
    XMLDictionaryNodeNameModeRootOnly = 0, //default 
    XMLDictionaryNodeNameModeAlways, 
    XMLDictionaryNodeNameModeNever 
}; 


static NSString *const XMLDictionaryAttributesKey = @"__attributes"; 
static NSString *const XMLDictionaryCommentsKey  = @"__comments"; 
static NSString *const XMLDictionaryTextKey   = @"__text"; 
static NSString *const XMLDictionaryNodeNameKey  = @"__name"; 
static NSString *const XMLDictionaryAttributePrefix = @"_"; 


@interface XMLURLParser : NSObject <NSCopying> 

+ (XMLURLParser *)sharedInstance; 

@property (nonatomic, assign) BOOL collapseTextNodes; // defaults to YES 
@property (nonatomic, assign) BOOL stripEmptyNodes; // defaults to YES 
@property (nonatomic, assign) BOOL trimWhiteSpace; // defaults to YES 
@property (nonatomic, assign) BOOL alwaysUseArrays; // defaults to NO 
@property (nonatomic, assign) BOOL preserveComments; // defaults to NO 
@property (nonatomic, assign) BOOL wrapRootNode;  // defaults to NO 

@property (nonatomic, assign) XMLDictionaryAttributesMode attributesMode; 
@property (nonatomic, assign) XMLDictionaryNodeNameMode nodeNameMode; 

- (NSDictionary *)dictionaryWithParser:(NSXMLParser *)parser; 
- (NSDictionary *)dictionaryWithData:(NSData *)data; 
- (NSDictionary *)dictionaryWithString:(NSString *)string; 
- (NSDictionary *)dictionaryWithFile:(NSString *)path; 

@end 


@interface NSDictionary (XMLParser) 

+ (NSDictionary *)dictionaryWithXMLParser:(NSXMLParser *)parser; 
+ (NSDictionary *)dictionaryWithXMLData:(NSData *)data; 
+ (NSDictionary *)dictionaryWithXMLString:(NSString *)string; 
+ (NSDictionary *)dictionaryWithXMLFile:(NSString *)path; 

- (NSDictionary *)attributes; 
- (NSDictionary *)childNodes; 
- (NSArray *)comments; 
- (NSString *)nodeName; 
- (NSString *)innerText; 
- (NSString *)innerXML; 
- (NSString *)XMLString; 

- (NSArray *)arrayValueForKeyPath:(NSString *)keyPath; 
- (NSString *)stringValueForKeyPath:(NSString *)keyPath; 
- (NSDictionary *)dictionaryValueForKeyPath:(NSString *)keyPath; 

@end 


@interface NSString (XMLParser) 

- (NSString *)XMLEncodedString; 

@end 


#pragma GCC diagnostic pop 

XMLParser.m

// 
// XMLParser.m 
// 
// 
// Copyright 2016 Darshan kunjadiya. All rights reserved. 


#import "XMLParser.h" 


#pragma GCC diagnostic ignored "-Wobjc-missing-property-synthesis" 
#pragma GCC diagnostic ignored "-Wdirect-ivar-access" 
#pragma GCC diagnostic ignored "-Wformat-non-iso" 
#pragma GCC diagnostic ignored "-Wgnu" 


#import <Availability.h> 
#if !__has_feature(objc_arc) 
#error This class requires automatic reference counting 
#endif 


@interface XMLURLParser() <NSXMLParserDelegate> 

@property (nonatomic, strong) NSMutableDictionary *root; 
@property (nonatomic, strong) NSMutableArray *stack; 
@property (nonatomic, strong) NSMutableString *text; 

@end 


@implementation XMLURLParser 

+ (XMLURLParser *)sharedInstance 
{ 
    static dispatch_once_t once; 
    static XMLURLParser *sharedInstance; 
    dispatch_once(&once, ^{ 

     sharedInstance = [[XMLURLParser alloc] init]; 
    }); 
    return sharedInstance; 
} 

- (id)init 
{ 
    if ((self = [super init])) 
    { 
     _collapseTextNodes = YES; 
     _stripEmptyNodes = YES; 
     _trimWhiteSpace = YES; 
     _alwaysUseArrays = NO; 
     _preserveComments = NO; 
     _wrapRootNode = NO; 
    } 
    return self; 
} 

- (id)copyWithZone:(NSZone *)zone 
{ 
    XMLURLParser *copy = [[[self class] allocWithZone:zone] init]; 
    copy.collapseTextNodes = _collapseTextNodes; 
    copy.stripEmptyNodes = _stripEmptyNodes; 
    copy.trimWhiteSpace = _trimWhiteSpace; 
    copy.alwaysUseArrays = _alwaysUseArrays; 
    copy.preserveComments = _preserveComments; 
    copy.attributesMode = _attributesMode; 
    copy.nodeNameMode = _nodeNameMode; 
    copy.wrapRootNode = _wrapRootNode; 
    return copy; 
} 

- (NSDictionary *)dictionaryWithParser:(NSXMLParser *)parser 
{ 
    [parser setDelegate:self]; 
    [parser parse]; 
    id result = _root; 
    _root = nil; 
    _stack = nil; 
    _text = nil; 
    return result; 
} 

- (NSDictionary *)dictionaryWithData:(NSData *)data 
{ 
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; 
    return [self dictionaryWithParser:parser]; 
} 

- (NSDictionary *)dictionaryWithString:(NSString *)string 
{ 
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; 
    return [self dictionaryWithData:data]; 
} 

- (NSDictionary *)dictionaryWithFile:(NSString *)path 
{ 
    NSData *data = [NSData dataWithContentsOfFile:path]; 
    return [self dictionaryWithData:data]; 
} 

+ (NSString *)XMLStringForNode:(id)node withNodeName:(NSString *)nodeName 
{ 
    if ([node isKindOfClass:[NSArray class]]) 
    { 
     NSMutableArray *nodes = [NSMutableArray arrayWithCapacity:[node count]]; 
     for (id individualNode in node) 
     { 
      [nodes addObject:[self XMLStringForNode:individualNode withNodeName:nodeName]]; 
     } 
     return [nodes componentsJoinedByString:@"\n"]; 
    } 
    else if ([node isKindOfClass:[NSDictionary class]]) 
    { 
     NSDictionary *attributes = [(NSDictionary *)node attributes]; 
     NSMutableString *attributeString = [NSMutableString string]; 
     for (NSString *key in [attributes allKeys]) 
     { 
      [attributeString appendFormat:@" %@=\"%@\"", [[key description] XMLEncodedString], [[attributes[key] description] XMLEncodedString]]; 
     } 

     NSString *innerXML = [node innerXML]; 
     if ([innerXML length]) 
     { 
      return [NSString stringWithFormat:@"<%[email protected]%[email protected]>%[email protected]</%[email protected]>", nodeName, attributeString, innerXML]; 
     } 
     else 
     { 
      return [NSString stringWithFormat:@"<%@%@/>", nodeName, attributeString]; 
     } 
    } 
    else 
    { 
     return [NSString stringWithFormat:@"<%[email protected]>%[email protected]</%[email protected]>", nodeName, [[node description] XMLEncodedString]]; 
    } 
} 

- (void)endText 
{ 
    if (_trimWhiteSpace) 
    { 
     _text = [[_text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] mutableCopy]; 
    } 
    if ([_text length]) 
    { 
     NSMutableDictionary *top = [_stack lastObject]; 
     id existing = top[XMLDictionaryTextKey]; 
     if ([existing isKindOfClass:[NSArray class]]) 
     { 
      [existing addObject:_text]; 
     } 
     else if (existing) 
     { 
      top[XMLDictionaryTextKey] = [@[existing, _text] mutableCopy]; 
     } 
     else 
     { 
      top[XMLDictionaryTextKey] = _text; 
     } 
    } 
    _text = nil; 
} 

- (void)addText:(NSString *)text 
{ 
    if (!_text) 
    { 
     _text = [NSMutableString stringWithString:text]; 
    } 
    else 
    { 
     [_text appendString:text]; 
    } 
} 

- (void)parser:(__unused NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(__unused NSString *)namespaceURI qualifiedName:(__unused NSString *)qName attributes:(NSDictionary *)attributeDict 
{ 
    [self endText]; 

    NSMutableDictionary *node = [NSMutableDictionary dictionary]; 
    switch (_nodeNameMode) 
    { 
     case XMLDictionaryNodeNameModeRootOnly: 
     { 
      if (!_root) 
      { 
       node[XMLDictionaryNodeNameKey] = elementName; 
      } 
      break; 
     } 
     case XMLDictionaryNodeNameModeAlways: 
     { 
      node[XMLDictionaryNodeNameKey] = elementName; 
      break; 
     } 
     case XMLDictionaryNodeNameModeNever: 
     { 
      break; 
     } 
    } 

    if ([attributeDict count]) 
    { 
     switch (_attributesMode) 
     { 
      case XMLDictionaryAttributesModePrefixed: 
      { 
       for (NSString *key in [attributeDict allKeys]) 
       { 
        node[[XMLDictionaryAttributePrefix stringByAppendingString:key]] = attributeDict[key]; 
       } 
       break; 
      } 
      case XMLDictionaryAttributesModeDictionary: 
      { 
       node[XMLDictionaryAttributesKey] = attributeDict; 
       break; 
      } 
      case XMLDictionaryAttributesModeUnprefixed: 
      { 
       [node addEntriesFromDictionary:attributeDict]; 
       break; 
      } 
      case XMLDictionaryAttributesModeDiscard: 
      { 
       break; 
      } 
     } 
    } 

    if (!_root) 
    { 
     _root = node; 
     _stack = [NSMutableArray arrayWithObject:node]; 
     if (_wrapRootNode) 
     { 
      _root = [NSMutableDictionary dictionaryWithObject:_root forKey:elementName]; 
      [_stack insertObject:_root atIndex:0]; 
     } 
    } 
    else 
    { 
     NSMutableDictionary *top = [_stack lastObject]; 
     id existing = top[elementName]; 
     if ([existing isKindOfClass:[NSArray class]]) 
     { 
      [existing addObject:node]; 
     } 
     else if (existing) 
     { 
      top[elementName] = [@[existing, node] mutableCopy]; 
     } 
     else if (_alwaysUseArrays) 
     { 
      top[elementName] = [NSMutableArray arrayWithObject:node]; 
     } 
     else 
     { 
      top[elementName] = node; 
     } 
     [_stack addObject:node]; 
    } 
} 

- (NSString *)nameForNode:(NSDictionary *)node inDictionary:(NSDictionary *)dict 
{ 
    if (node.nodeName) 
    { 
     return node.nodeName; 
    } 
    else 
    { 
     for (NSString *name in dict) 
     { 
      id object = dict[name]; 
      if (object == node) 
      { 
       return name; 
      } 
      else if ([object isKindOfClass:[NSArray class]] && [object containsObject:node]) 
      { 
       return name; 
      } 
     } 
    } 
    return nil; 
} 

- (void)parser:(__unused NSXMLParser *)parser didEndElement:(__unused NSString *)elementName namespaceURI:(__unused NSString *)namespaceURI qualifiedName:(__unused NSString *)qName 
{ 
    [self endText]; 

    NSMutableDictionary *top = [_stack lastObject]; 
    [_stack removeLastObject]; 

    if (!top.attributes && !top.childNodes && !top.comments) 
    { 
     NSMutableDictionary *newTop = [_stack lastObject]; 
     NSString *nodeName = [self nameForNode:top inDictionary:newTop]; 
     if (nodeName) 
     { 
      id parentNode = newTop[nodeName]; 
      if (top.innerText && _collapseTextNodes) 
      { 
       if ([parentNode isKindOfClass:[NSArray class]]) 
       { 
        parentNode[[parentNode count] - 1] = top.innerText; 
       } 
       else 
       { 
        newTop[nodeName] = top.innerText; 
       } 
      } 
      else if (!top.innerText && _stripEmptyNodes) 
      { 
       if ([parentNode isKindOfClass:[NSArray class]]) 
       { 
        [parentNode removeLastObject]; 
       } 
       else 
       { 
        [newTop removeObjectForKey:nodeName]; 
       } 
      } 
      else if (!top.innerText && !_collapseTextNodes && !_stripEmptyNodes) 
      { 
       top[XMLDictionaryTextKey] = @""; 
      } 
     } 
    } 
} 

- (void)parser:(__unused NSXMLParser *)parser foundCharacters:(NSString *)string 
{ 
    [self addText:string]; 
} 

- (void)parser:(__unused NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock 
{ 
    [self addText:[[NSString alloc] initWithData:CDATABlock encoding:NSUTF8StringEncoding]]; 
} 

- (void)parser:(__unused NSXMLParser *)parser foundComment:(NSString *)comment 
{ 
    if (_preserveComments) 
    { 
     NSMutableDictionary *top = [_stack lastObject]; 
     NSMutableArray *comments = top[XMLDictionaryCommentsKey]; 
     if (!comments) 
     { 
      comments = [@[comment] mutableCopy]; 
      top[XMLDictionaryCommentsKey] = comments; 
     } 
     else 
     { 
      [comments addObject:comment]; 
     } 
    } 
} 

@end 


@implementation NSDictionary(XMLDictionary) 

+ (NSDictionary *)dictionaryWithXMLParser:(NSXMLParser *)parser 
{ 
    return [[[XMLURLParser sharedInstance] copy] dictionaryWithParser:parser]; 
} 

+ (NSDictionary *)dictionaryWithXMLData:(NSData *)data 
{ 
    return [[[XMLURLParser sharedInstance] copy] dictionaryWithData:data]; 
} 

+ (NSDictionary *)dictionaryWithXMLString:(NSString *)string 
{ 
    return [[[XMLURLParser sharedInstance] copy] dictionaryWithString:string]; 
} 

+ (NSDictionary *)dictionaryWithXMLFile:(NSString *)path 
{ 
    return [[[XMLURLParser sharedInstance] copy] dictionaryWithFile:path]; 
} 

- (NSDictionary *)attributes 
{ 
    NSDictionary *attributes = self[XMLDictionaryAttributesKey]; 
    if (attributes) 
    { 
     return [attributes count]? attributes: nil; 
    } 
    else 
    { 
     NSMutableDictionary *filteredDict = [NSMutableDictionary dictionaryWithDictionary:self]; 
     [filteredDict removeObjectsForKeys:@[XMLDictionaryCommentsKey, XMLDictionaryTextKey, XMLDictionaryNodeNameKey]]; 
     for (NSString *key in [filteredDict allKeys]) 
     { 
      [filteredDict removeObjectForKey:key]; 
      if ([key hasPrefix:XMLDictionaryAttributePrefix]) 
      { 
       filteredDict[[key substringFromIndex:[XMLDictionaryAttributePrefix length]]] = self[key]; 
      } 
     } 
     return [filteredDict count]? filteredDict: nil; 
    } 
    return nil; 
} 

- (NSDictionary *)childNodes 
{ 
    NSMutableDictionary *filteredDict = [self mutableCopy]; 
    [filteredDict removeObjectsForKeys:@[XMLDictionaryAttributesKey, XMLDictionaryCommentsKey, XMLDictionaryTextKey, XMLDictionaryNodeNameKey]]; 
    for (NSString *key in [filteredDict allKeys]) 
    { 
     if ([key hasPrefix:XMLDictionaryAttributePrefix]) 
     { 
      [filteredDict removeObjectForKey:key]; 
     } 
    } 
    return [filteredDict count]? filteredDict: nil; 
} 

- (NSArray *)comments 
{ 
    return self[XMLDictionaryCommentsKey]; 
} 

- (NSString *)nodeName 
{ 
    return self[XMLDictionaryNodeNameKey]; 
} 

- (id)innerText 
{ 
    id text = self[XMLDictionaryTextKey]; 
    if ([text isKindOfClass:[NSArray class]]) 
    { 
     return [text componentsJoinedByString:@"\n"]; 
    } 
    else 
    { 
     return text; 
    } 
} 

- (NSString *)innerXML 
{ 
    NSMutableArray *nodes = [NSMutableArray array]; 

    for (NSString *comment in [self comments]) 
    { 
     [nodes addObject:[NSString stringWithFormat:@"<!--%@-->", [comment XMLEncodedString]]]; 
    } 

    NSDictionary *childNodes = [self childNodes]; 
    for (NSString *key in childNodes) 
    { 
     [nodes addObject:[XMLURLParser XMLStringForNode:childNodes[key] withNodeName:key]]; 
    } 

    NSString *text = [self innerText]; 
    if (text) 
    { 
     [nodes addObject:[text XMLEncodedString]]; 
    } 

    return [nodes componentsJoinedByString:@"\n"]; 
} 

- (NSString *)XMLString 
{ 
    if ([self count] == 1 && ![self nodeName]) 
    { 
     //ignore outermost dictionary 
     return [self innerXML]; 
    } 
    else 
    { 
     return [XMLURLParser XMLStringForNode:self withNodeName:[self nodeName] ?: @"root"]; 
    } 
} 

- (NSArray *)arrayValueForKeyPath:(NSString *)keyPath 
{ 
    id value = [self valueForKeyPath:keyPath]; 
    if (value && ![value isKindOfClass:[NSArray class]]) 
    { 
     return @[value]; 
    } 
    return value; 
} 

- (NSString *)stringValueForKeyPath:(NSString *)keyPath 
{ 
    id value = [self valueForKeyPath:keyPath]; 
    if ([value isKindOfClass:[NSArray class]]) 
    { 
     value = [value count]? value[0]: nil; 
    } 
    if ([value isKindOfClass:[NSDictionary class]]) 
    { 
     return [(NSDictionary *)value innerText]; 
    } 
    return value; 
} 

- (NSDictionary *)dictionaryValueForKeyPath:(NSString *)keyPath 
{ 
    id value = [self valueForKeyPath:keyPath]; 
    if ([value isKindOfClass:[NSArray class]]) 
    { 
     value = [value count]? value[0]: nil; 
    } 
    if ([value isKindOfClass:[NSString class]]) 
    { 
     return @{XMLDictionaryTextKey: value}; 
    } 
    return value; 
} 

@end 


@implementation NSString (XMLDictionary) 

- (NSString *)XMLEncodedString 
{ 
    return [[[[[self stringByReplacingOccurrencesOfString:@"&" withString:@"&amp;"] 
       stringByReplacingOccurrencesOfString:@"<" withString:@"&lt;"] 
       stringByReplacingOccurrencesOfString:@">" withString:@"&gt;"] 
      stringByReplacingOccurrencesOfString:@"\"" withString:@"&quot;"] 
      stringByReplacingOccurrencesOfString:@"\'" withString:@"&apos;"]; 
} 

@end 

espero que esta respuesta es útil para usted.

+0

Esto crea un problema cuando hay una matriz de diccionario: | – DivineDesert

+2

¡Esto crea muchos problemas para la codificación basada en ARC! ¡Arreglalo! –

+0

@JayprakashDubey bien, verificaré y actualizaré esta respuesta. –