Latest | 0.9.1 |
---|---|
Homepage | https://github.com/siuying/IGHTMLQuery |
License | MIT |
Platforms | ios 7.0, osx 10.9, requires ARC |
Authors |
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:
- Add all the source files in
Classes
to your Xcoe project - In "Build Phases" > "Link Binary With Libraries, add
libxml2
. - 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.
Latest podspec
{ "name": "IGHTMLQuery", "version": "0.9.1", "summary": "IGHTMLQuery is a lightweight XML/HTML parser for iOS, built on top of libxml.", "description": "IGHTMLQuery is a lightweight XML/HTML parser for iOS, built on top of libxml.nn* XPath support for document searching.n* jQuery style chainable syntax.n* XML traversal and manipulation.", "homepage": "https://github.com/siuying/IGHTMLQuery", "license": { "type": "MIT", "file": "LICENSE.txt" }, "authors": { "Francis Chong": "[email protected]" }, "source": { "git": "https://github.com/siuying/IGHTMLQuery.git", "tag": "0.9.1" }, "libraries": "xml2", "requires_arc": true, "xcconfig": { "HEADER_SEARCH_PATHS": "$(SDKROOT)/usr/include/libxml2" }, "default_subspecs": "Core", "platforms": { "ios": "7.0", "osx": "10.9" }, "subspecs": [ { "name": "Core", "platforms": { "ios": "7.0", "osx": "10.9" }, "source_files": "IGHTMLQuery/Classes/**/*.{h,m}", "exclude_files": [ "IGHTMLQuery/Classes/JSContext+IGHTMLQueryRubyAdditions.{h,m}" ], "dependencies": { "CSSSelectorConverter": [ ">= 1.2.0" ] }, "private_header_files": "IGHTMLQuery/Classes/Private/*.h" }, { "name": "JavaScript", "platforms": { "ios": "7.0", "osx": "10.9" }, "prefix_header_contents": "#define IGHTMLQUERY_JAVSCRIPT_EXPORT", "dependencies": { "CSSSelectorConverter": [ ">= 1.2.0" ] }, "frameworks": "JavaScriptCore", "source_files": "IGHTMLQuery/Classes/**/*.{h,m}", "exclude_files": "IGHTMLQuery/Classes/JSContext+IGHTMLQueryRubyAdditions.{h,m}", "private_header_files": "IGHTMLQuery/Classes/Private/*.h" }, { "name": "Ruby", "platforms": { "ios": "8.0", "osx": "10.9" }, "prefix_header_contents": "#define IGHTMLQUERY_JAVSCRIPT_EXPORTn#define IGHTMLQUERY_RUBY_EXPORT", "dependencies": { "CSSSelectorConverter": [ ">= 1.2.0" ], "JavaScriptCoreOpalAdditions": [ ">= 0.5.1" ] }, "frameworks": "JavaScriptCore", "source_files": "IGHTMLQuery/Classes/**/*.{h,m}", "resources": [ "IGHTMLQuery/JavaScript/*.js", "IGHTMLQuery/Ruby/*.rb" ], "private_header_files": "IGHTMLQuery/Classes/Private/*.h" } ] }
Mon, 29 Feb 2016 04:17:02 +0000