2012-07-04 49 views
15

Xin chào, tôi đang tạo một ứng dụng phải in một giá trị trong nhãn từ tệp xml trong máy chủ. Tôi đã thử đọc một số tài liệu trong tìm kiếm của Google .. nhưng tôi không thể tìm thấy nó .. .Không ai biết hướng dẫn đơn giản hoặc bất kỳ mã mẫu nào được sử dụng để tích hợp phân tích cú pháp xml trong ứng dụng của tôi.Xml phân tích cú pháp trong hướng dẫn iOS

+0

http://developer.apple.com/library/ios/#samplecode/XMLPerformance/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008094. Hy vọng mã ví dụ này sẽ giúp bạn, – Neo

Trả lời

5

Sử dụng trình phân tích cú pháp TBX..Đó là cách dễ nhất và cũng mất ít thời gian hơn để phân tích giá trị..U có thể tải xuống dự án TBXMLDemo trên github và in thay vì nhãn u có thể sử dụng ô xem bảng và chọn nó làm null.So rằng nó trông giống như simillarly label.If u cần thêm chi tiết bình luận cho tôi, .. tôi sẽ được giúp đỡ nó ..

19

Bạn có thể phân tích XML với mã dưới đây. Nhưng bạn phải tạo các lớp mà bạn có thể tìm thấy bên dưới.

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

Bạn cần phải tạo các lớp học này cho XML phân tích với tên của 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 

tôi hy vọng câu trả lời này là hữu ích cho bạn.

+0

Điều này tạo ra vấn đề khi có mảng từ điển: | – DivineDesert

+2

Điều này tạo ra rất nhiều vấn đề cho mã hóa dựa trên ARC !! Sửa nó! –

+0

@JayprakashDubey okay tôi sẽ kiểm tra và cập nhật câu trả lời này. –

Các vấn đề liên quan