2014-02-21 72 views
0

我想解析如下的XML。NSXMLParser不解析html标签

<xml> 
<item> 
<title> 
21/2/2014 13:18:22 
</title> 
<time> 
2014-02-21 02:49:03 
</time> 
<message> 
<strong> 
abcd</strong><br /><br /><em>abcd</em><br /><br /><u>abcd</u><br /><br /><br /> 
</message> 
</item> 
<item> 
<title> 
21/2/2014 12:9:40 
</title> 
<time> 
2014-02-21 01:57:28 
</time> 
<message> 
100 
</message> 
</item> 
</xml> 

我使用的是正常的解析过程

我Parser.h

#import "XMLData.h" 
@interface XMLParser : NSObject<NSXMLParserDelegate> 
{  
    NSMutableString *currentNodeContent; 
    NSMutableArray *datas; 
    NSXMLParser  *parser; 
    XMLData  *recentEnquiry; 
} 
@property (readonly, retain) NSMutableArray *datas; 

-(id) loadXMLByURL:(NSString *)urlString; 

我Parser.m的第一个项目解析

#import "XMLParser.h" 

@implementation XMLParser 
@synthesize datas; 

-(id) loadXMLByURL:(NSString *)urlString 
{ 
    datas   = [[NSMutableArray alloc] init]; 
    NSURL *url  = [NSURL URLWithString:urlString]; 
    NSData *data = [[NSData alloc] initWithContentsOfURL:url]; 
    NSLog(@"Data is %@",data); 
    parser   = [[NSXMLParser alloc] initWithData:data]; 
    parser.delegate = self; 
    [parser parse]; 
    return self; 
} 

- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 
{ 
    if ([elementname isEqualToString:@"item"]) 
    { 
     recentEnquiry = [XMLData alloc]; 
    } 
} 

- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
{ 
    if ([elementname isEqualToString:@"title"]) 
    { 
     recentEnquiry.title = currentNodeContent; 

    } 
    if ([elementname isEqualToString:@"time"]) 
    { 
     recentEnquiry.time = currentNodeContent; 
    } 
    if ([elementname isEqualToString:@"message"]) 
    { 
     recentEnquiry.message = currentNodeContent; 
     [datas addObject:recentEnquiry]; 
    } 
} 

- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
{ 
    currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
} 

@end 

然而我只是ge t“>”作为消息,我应该将文本嵌入到html标记中。我读了解其他解析技术,知道NSXMParser的缺点,但我只想要文本。我会自己转换并分割html。请帮助我。

N:B: - 我正在用foundCharacters方法中的html标签获取所需的文本,但它们进入循环。

+0

对不起,好像它不是HTML – Injectios

+0

@Injectios请看第一项的消息节点。你会看到html标签。 – Saty

+0

那么我应该怎么做才能解析这些标签。你有什么主意吗? – Saty

回答

0

有两个问题在这里:

  1. XML是不是精心设计的:你message元素的内容应该编码的HTML。一种方法是更换<>,并&&lt;&gt;&amp;

    <xml> 
    <item> 
    <title> 
    21/2/2014 13:18:22 
    </title> 
    <time> 
    2014-02-21 02:49:03 
    </time> 
    <message> 
    &lt;strong&gt; 
    abcd&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;abcd&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;abcd&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; 
    </message> 
    </item> 
    <item> 
    <title> 
    21/2/2014 12:9:40 
    </title> 
    <time> 
    2014-02-21 01:57:28 
    </time> 
    <message> 
    100 
    </message> 
    </item> 
    </xml> 
    

    或者,由Daij-Djan描述,您可以使用CDATA(与<![CDATA[打开和]]>终止):

    <xml> 
    <item> 
    <title> 
    21/2/2014 13:18:22 
    </title> 
    <time> 
    2014-02-21 02:49:03 
    </time> 
    <message> 
    <![CDATA[ 
    <strong> 
    abcd</strong><br /><br /><em>abcd</em><br /><br /><u>abcd</u><br /><br /><br /> 
    ]]> 
    </message> 
    </item> 
    <item> 
    <title> 
    21/2/2014 12:9:40 
    </title> 
    <time> 
    2014-02-21 01:57:28 
    </time> 
    <message> 
    100 
    </message> 
    </item> 
    </xml> 
    

    有关在XML处理的<>&保留字符的更多信息,请参见2.4 Character Data and Markup,XML规范。

  2. 您的foundCharacters错误地假定字段的内容将始终由对该方法的单个调用返回。这不是一个有效的假设。您应始终假定可能需要多次致电foundCharacters才能返回整个值。因此,在didStartElement中实例化currentNodeElement,将其附加到foundCharacters中,并将其保存并重置为didEndElement。因此,你可能想是这样的:

    - (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 
    { 
        if ([elementname isEqualToString:@"item"]) 
        { 
         recentEnquiry = [[XMLData alloc] init]; 
        } 
        else if ([elementname isEqualToString:@"title"] || [elementname isEqualToString:@"time"] || [elementname isEqualToString:@"message"]) 
        { 
         currentNodeContent = [NSMutableString string]; 
        } 
    } 
    
    - (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
    { 
        if ([elementname isEqualToString:@"title"]) 
        { 
         recentEnquiry.title = [currentNodeContent stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
        } 
        else if ([elementname isEqualToString:@"time"]) 
        { 
         recentEnquiry.time = [currentNodeContent stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
        } 
        else if ([elementname isEqualToString:@"message"]) 
        { 
         recentEnquiry.message = [currentNodeContent stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
        } 
        else if ([elementname isEqualToString:@"item"]) 
        { 
         [datas addObject:recentEnquiry]; 
        } 
    
        currentNodeContent = nil; 
    } 
    
    - (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
    { 
        [currentNodeContent appendString:string]; // do not trim whitespace here 
    } 
    

    显然,currentNodeContent应该被定义为NSMutableString,而不仅仅是一个NSString