在开发中,大部分会使用 JSON 进行数据解析,偶尔会用到 HTML。

  使用 Objective-C 解析 HTML 或者 XML,系统自带有两种方式一个是通过 libxml,一个是通过 NSXMLParser。

  libxml性能较好,且可以结合urlconnection实现边下载边解析,在要求快速 、分批响应UI到情况下较为有用,NSXMLParser基本没什么优势,不如使用第三方工具。

  Hpple,它是一个轻量级的包装框架,可以很好的解决这个问题,尤其是它支持HTML的解析,是其他XML类库所不及的地方,它是用XPath来定位和解析HTML或者XML。

  使用方法:

  1> 在 GitHub 上下载 Hpple

  2> 把 Hpple 文件夹拖进项目工程;

  3> 添加依赖库 libxml2.2.dylib、

  4> 配置 libxml2.2 索引路径(否则编译报错)如图

  

  解析本地 HTML 文件:

NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"]];
TFHpple *doc = [[TFHpple alloc] initWithHTMLData:data];
NSArray *elements = [doc searchWithXPathQuery:@"//a[@class='sponsor']"];
TFHppleElement *element = [elements objectAtIndex:];
[element text]; // The text inside the HTML element (the content of the first text node)
[element tagName]; // "a"
[element attributes]; // NSDictionary of href, class, id, etc.
[element objectForKey:@"href"]; // Easy access to single attribute
[element firstChildWithTagName:@"b"]; // The first "b" child node
NSLog(@"%@\ntxt = %@\n tagName = %@\n attributes = %@", elements,[element text],[element tagName],[element attributes]);

  解析网络HTML:

NSData *htmlData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://world.chinadaily.com.cn/2017-08/02/content_30329852.htm"]];
TFHpple *xpathParser = [[TFHpple alloc] initWithHTMLData:htmlData];
NSArray *divArray = [xpathParser searchWithXPathQuery:@"//div[@class=\"article\"]"];
NSMutableString *str = [[NSMutableString alloc] init];
TFHppleElement *element = [divArray objectAtIndex:];
[str appendString:[element content]];
NSLog(@"%@", str);

  HTML 解析测试:

- (void)setUp
{
NSBundle *testBundle = [NSBundle bundleForClass:[self class]];
NSURL *testFileUrl = [testBundle URLForResource:TEST_DOCUMENT_NAME withExtension:TEST_DOCUMENT_EXTENSION];
NSData * data = [NSData dataWithContentsOfURL:testFileUrl];
self.doc = [[TFHpple alloc] initWithHTMLData:data];
} - (void)testInitializesWithHTMLData
{
XCTAssertNotNil(self.doc.data);
XCTAssertTrue([self.doc isMemberOfClass:[TFHpple class]]);
} // doc.search("//p[@class='posted']")
- (void)testSearchesWithXPath
{
NSArray *a = [self.doc searchWithXPathQuery:@"//a[@class='sponsor']"];
XCTAssertEqual([a count], ); TFHppleElement * e = [a objectAtIndex:];
XCTAssertTrue([e isMemberOfClass:[TFHppleElement class]]);
} - (void)testFindsFirstElementAtXPath
{
TFHppleElement *e = [self.doc peekAtSearchWithXPathQuery:@"//a[@class='sponsor']"]; XCTAssertEqualObjects([e content], @"RailsMachine");
XCTAssertEqualObjects([e tagName], @"a");
} - (void)testSearchesByNestedXPath
{
NSArray *a = [self.doc searchWithXPathQuery:@"//div[@class='column']//strong"];
XCTAssertEqual([a count], ); TFHppleElement * e = [a objectAtIndex:];
XCTAssertEqualObjects([e content], @"PeepCode");
} - (void)testPopulatesAttributes
{
TFHppleElement *e = [self.doc peekAtSearchWithXPathQuery:@"//a[@class='sponsor']"]; XCTAssertTrue([[e attributes] isKindOfClass:[NSDictionary class]]);
XCTAssertEqualObjects([[e attributes] objectForKey:@"href"], @"http://railsmachine.com/");
} - (void)testProvidesEasyAccessToAttributes
{
TFHppleElement *e = [self.doc peekAtSearchWithXPathQuery:@"//a[@class='sponsor']"]; XCTAssertEqualObjects([e objectForKey:@"href"], @"http://railsmachine.com/");
}

  XML 解析测试:

- (void)setUp
{
[super setUp]; NSBundle *testBundle = [NSBundle bundleForClass:[self class]];
NSURL *testFileUrl = [testBundle URLForResource:TEST_DOCUMENT_NAME withExtension:TEST_DOCUMENT_EXTENSION];
NSData * data = [NSData dataWithContentsOfURL:testFileUrl];
self.doc = [[TFHpple alloc] initWithXMLData:data];
} - (void)testInitializesWithXMLData
{
XCTAssertNotNil(self.doc.data);
XCTAssertTrue([self.doc isMemberOfClass:[TFHpple class]]);
} // item/title,description,link
- (void)testSearchesWithXPath
{
NSArray *items = [self.doc searchWithXPathQuery:@"//item"];
XCTAssertEqual([items count], 0x0f); TFHppleElement * e = [items objectAtIndex:];
XCTAssertTrue([e isMemberOfClass:[TFHppleElement class]]);
} - (void)testFindsFirstElementAtXPath
{
TFHppleElement *e = [self.doc peekAtSearchWithXPathQuery:@"//item/title"]; XCTAssertEqualObjects([e content], @"Objective-C for Rubyists");
XCTAssertEqualObjects([e tagName], @"title");
} - (void)testSearchesByNestedXPath
{
NSArray *elements = [self.doc searchWithXPathQuery:@"//item/title"];
XCTAssertEqual([elements count], 0x0f); TFHppleElement * e = [elements objectAtIndex:];
XCTAssertEqualObjects([e content], @"Objective-C for Rubyists");
} - (void)testAtSafelyReturnsNilIfEmpty
{
TFHppleElement * e = [self.doc peekAtSearchWithXPathQuery:@"//a[@class='sponsor']"];
XCTAssertEqualObjects(e, nil);
} // Other Hpricot methods:
// doc.at("body")['onload']
// (doc/"#elementID").inner_html
// (doc/"#elementID").to_html
// doc.at("div > div:nth(1)").css_path
// doc.at("div > div:nth(1)").xpath

  字符串解析测试:

- (void)setUp {
[super setUp]; NSString *htmlString = @"String with a link <a href=\"http://www.google.com\">This is a link</a> and the end";
NSData *data = [htmlString dataUsingEncoding:NSUTF8StringEncoding];
self.doc = [[TFHpple alloc] initWithHTMLData:data];
} - (void)testTextNodeCount
{
NSArray *textNodes = [self.doc searchWithXPathQuery:@"//text()"];
XCTAssertEqual(textNodes.count, );
} - (void)testFirstTextNodeContent
{
TFHppleElement *e = [self.doc peekAtSearchWithXPathQuery:@"//text()"];
XCTAssertEqualObjects([e content], @"String with a link ");
} - (void)testALinkContent
{
TFHppleElement *e = [self.doc peekAtSearchWithXPathQuery:@"//a"];
XCTAssertEqualObjects([e content], @"This is a link"); } - (void)testHref
{
TFHppleElement *e = [self.doc peekAtSearchWithXPathQuery:@"//a"];
XCTAssertEqualObjects([e objectForKey:@"href"], @"http://www.google.com");
}

  

最新文章

  1. JavaScript动画-磁性吸附
  2. CSS3按钮鼠标悬浮光圈效果
  3. STM32 DMA使用详解
  4. 通过微信查找SAP TCODE代码
  5. 不使用ajax,无刷新提交表单
  6. Path,Files巩固,题目:从键盘接收两个文件夹路径,把其中一个文件夹中(包含内容)拷贝到另一个文件夹中
  7. npm命令大全
  8. Spark Streaming揭秘 Day6 关于SparkStreaming Job的一些思考
  9. c++二分答案 之 跳石头
  10. [Linux]ubuntu安装ftp服务器
  11. 二十七、Java图形化界面设计——容器(JFrame)
  12. java分页数据导出excel
  13. Delphi控件下载网
  14. JSON支持什么对象/类型?
  15. HTML5拖动画布/拖放
  16. Java虚拟机15:再谈四种引用状态
  17. 小程序 for循环 报错 Cannot read property &#39;total&#39; of undefined
  18. 使用PageHepler分页
  19. Windows10下 tensorflow-gpu 配置
  20. 认识MySQL中的索引

热门文章

  1. 关于static 关键字的总结
  2. [Java] 多线程基础详细总结,附加详细实例
  3. python测量代码运行时间方法
  4. 第二十九篇 玩转数据结构——线段树(Segment Tree)
  5. GM2引擎脚本召唤宝宝说明
  6. jq的 on 事件委托 导致多次执行问题
  7. numpy函数hstack,vstack,dstack简介
  8. python自动更新升级失败解决方案
  9. spring 基于xml的申明式AspectH中的后置通知的返回值获取
  10. wordpress 上传图片出现权限或者http错误