NSXMLParser不解析HTML标记

时间:2014-02-21 12:10:23

标签: ios nsxmlparser nsmutablestring

我正在尝试解析XML,如下所示。

<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

然而,对于第一项我只是得到“&gt;”作为我应该在html标签中嵌入文本的消息。我读到了其他解析技术,知道NSXMParser的缺点,但我只想要文本。我将自己转换并拆分html。

注意:我在foundCharacters方法中使用html标签获取所需的文本,但它们会循环播放。

1 个答案:

答案 0 :(得分: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中<>&的保留字符的详细信息,请参阅XML规范的2.4 Character Data and Markup部分。

  2. 您的foundCharacters错误地认为只需调用该方法即可返回字段内容。这不是一个有效的假设。您应该始终假设可能需要多次调用foundCharacters才能返回整个值。因此,在currentNodeElement中实例化didStartElement,在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,而不仅仅是{{1}}。