IGHTMLQuery

IGHTMLQuery is a lightweight XML/HTML parser for Objective-C, built on top of libxml.

  • Owner: siuying/IGHTMLQuery
  • Platform:
  • License:: MIT License
  • Category::
  • Topic:
  • Like:
    0
      Compare:

Github stars Tracking Chart

What is it?

IGHTMLQuery is a lightweight XML/HTML parser for iOS, built on top of libxml. It is inspired by jQuery and nokogiri. Consider following snippets:

IGXMLDocument* node = [[IGXMLDocument alloc] initWithXMLString:catelogXml error:nil];
NSString* title = [[[node queryWithXPath:@"//cd/title"] firstObject] text];
[[node queryWithXPath:@"//title"] enumerateNodesUsingBlock:^(IGXMLNode *title, NSUInteger idx, BOOL *stop) {
    NSLog(@"title = %@", title.text);
}];

// or use CSS Selector
[[node queryWithCSS:@"title"] enumerateNodesUsingBlock:^(IGXMLNode *title, NSUInteger idx, BOOL *stop) {
    NSLog(@"title = %@", title.text);
}];

// quick manipulation
[[node queryWithXPath:@"//title"] appendWithXMLString:@"<message>Hi!</message>"];

Features

  • Use XPath and CSS Selector for document searching.
  • jQuery style chainable syntax.
  • XML traversal and manipulation.

Installation

IGHTMLQuery is available through CocoaPods, to install it simply add the following line to your Podfile:

pod "IGHTMLQuery", "~> 0.8.4"

Alternatively:

  1. Add all the source files in Classes to your Xcoe project
  2. In "Build Phases" > "Link Binary With Libraries, add libxml2.
  3. In "Build Setting", find "Header Search Paths" and add "$(SDK_DIR)/usr/include/libxml2"

Usage

Import header

For each files using IGHTMLQuery, import IGHTMLQuery.h:

#import 'IGHTMLQuery.h'

Create a document

Create a XML document:

IGXMLDocument* node = [[IGXMLDocument alloc] initWithXMLString:xml error:nil];

Create a HTML document:

IGHTMLDocument* node = [[IGHTMLDocument alloc] initWithHTMLString:html error:nil];

Traversal

Use parent, nextSibling, previousSibling, children and firstChild to traverse the document.

Query using XPath or CSS Selector

You can query the document or any node with queryWithXPath: or queryWithCSS: methods. They will always return a IGXMLNodeSet object, which is a set like object that you can chain query and operations.

IGXMLNodeSet* contents = [doc queryWithXPath:@"//div[@class='content']"];
[contents enumerateNodesUsingBlock:^(IGXMLNode* content, NSUInteger idx, BOOL *stop){
    NSLog(@"%@", content.xml);
}];

// use a @try/@catch block for queryWithCSS, as it can throw an exception if 
// the CSS Selector cannot be converted to XPath.
@try {
  contents = [doc queryWithCSS:@"div.content"];
  [contents enumerateNodesUsingBlock:^(IGXMLNode* content, NSUInteger idx, BOOL *stop){
      NSLog(@"%@", content.xml);
  }];
} @catch(NSException * e) {
  // handle error
}

Document Manipulation

You can change the document using methods in IGXMLNodeManipulation protocol.

@protocol IGXMLNodeManipulation <NSObject>

-(instancetype) appendWithNode:(IGXMLNode*)child;

-(instancetype) prependWithNode:(IGXMLNode*)child;

-(instancetype) addChildWithNode:(IGXMLNode*)child;

-(instancetype) addNextSiblingWithNode:(IGXMLNode*)child;

-(instancetype) addPreviousSiblingWithNode:(IGXMLNode*)child;

-(void) empty;

-(void) remove;

@end

JavaScript/Ruby support

All classes in IGHTMLQuery supports JavaScriptCore exports. Additionally there
are Ruby wrappers to used with JavaScriptCoreOpalAdditions, which allow you to manipulate DOM with Ruby in Objective-C like this ...

#import "JSContext+IGHTMLQueryRubyAdditions.h"
#import "JSContext+OpalAdditions.h"

// load IGHTMLQuery ruby wrapper classes
[context configureIGHTMLQuery];

// create a lambda that evalulate script on the fly
JSValue* instanceEval = [context evaluateRuby:@"lambda {, doc, script, XMLNode.new(doc).instance_eval(&eval(\"lambda { #{script} }\")) }"];

// a simple script that find the title of first cd have a price less than 9.0
JSValue* node = [instanceEval callWithArguments:@[doc, @"self.xpath('//cd').find {, node, node.xpath('./price').text.to_f < 9.0 }.xpath('./title').text"]];

// convert the result to string
NSString* title = [node toString];
XCTAssertEqualObjects((@"Greatest Hits"), title, @"title should be Greatest Hits");

To use IGHTMLQuery with Ruby support, add following line to your Podfile:

pod "IGHTMLQuery/Ruby"

See Test Cases for more detail.

Breaking Changes

0.7.2

In previous version, the method [[IGHTMLDocument alloc] initWithHTMLString:] will create html element without implied HTML tag. (HTML_PARSE_NOIMPLIED option in libxml). Since 0.7.2, HTML_PARSE_NOIMPLIED will no longer be the default.

If you want to maintain the old behavior, check the [[IGHTMLDocument alloc] initWithHTMLFragmentString:] method.

License

MIT License.

Main metrics

Overview
Name With Ownersiuying/IGHTMLQuery
Primary LanguageObjective-C
Program languageRuby (Language Count: 4)
Platform
License:MIT License
所有者活动
Created At2013-08-20 16:01:01
Pushed At2018-12-06 13:48:38
Last Commit At2018-12-06 21:48:31
Release Count25
Last Release Name0.9.1 (Posted on )
First Release Name0.1.0 (Posted on )
用户参与
Stargazers Count279
Watchers Count13
Fork Count22
Commits Count204
Has Issues Enabled
Issues Count9
Issue Open Count1
Pull Requests Count2
Pull Requests Open Count2
Pull Requests Close Count0
项目设置
Has Wiki Enabled
Is Archived
Is Fork
Is Locked
Is Mirror
Is Private