iOS HTML Parse

iOSで, HTMLをパースします。このあたりも3rd Partyのライブラリを使った方が早い気がします。
確かにこの手のやつはすべてのHTMLに適用するのは難しいでしょう。JavaScriptとか, CSSとかありますし,
実際に必要な機能などは後から自分で足していけばよいのではないでしょうか。

さて本題ですが, Objective-C-HMTL-Parserというのがあります。これを利用してみましょう。
このライブラリのコード自体は, ARCです。Usageにあるサンプルでは, Non-Arcのコードで書いているみたいですが。
このライブラリは, libxml2を使っているみたいなので, libxml2.dylibのリンクが必要です

コンパイル•リンク

プロジェクトに組み込む準備をします。

  • libxml2(libxml2.dylib)をLink Binary With Librariesで追加
  • Header Search Pathsに, ${SDKROOT}/usr/include/libxml2を追加
  • コードをすべてプロジェクトにコピーします

コードは, HTMLNode, HTMLParserの2種類です。FrameworkやStaticライブラリにしてもよいでしょう。

さてサンプルですが, GitHubに書いています。
それをそのまま使えそうです(ただし, 最後の部分がNon-ARCになっているので, ARCであればはずしておきましょう。

ヘッダ

@interface HTMLSample : NSObject
-(void)sampleParse;
@end

コード

@implementation HTMLSample

-(void)sampleParse {
    NSError *error = nil;
    NSString *html =
    @"<ul>"
    "<li><input type='image' name='input1' value='string1value' /></li>"
    "<li><input type='image' name='input2' value='string2value' /></li>"
    "</ul>"
    "<span class='spantext'><b>Hello World 1</b></span>"
    "<span class='spantext'><b>Hello World 2</b></span>";
    HTMLParser *parser = [[HTMLParser alloc] initWithString:html error:&error];
    
    if (error) {
        NSLog(@"Error: %@", error);
        return;
    }
    
    HTMLNode *bodyNode = [parser body];
    
    NSArray *inputNodes = [bodyNode findChildTags:@"input"];
    
    for (HTMLNode *inputNode in inputNodes) {
        if ([[inputNode getAttributeNamed:@"name"] isEqualToString:@"input2"]) {
            NSLog(@"%@", [inputNode getAttributeNamed:@"value"]); //Answer to first question
        }
    }
    
    NSArray *spanNodes = [bodyNode findChildTags:@"span"];
    
    for (HTMLNode *spanNode in spanNodes) {
        if ([[spanNode getAttributeNamed:@"class"] isEqualToString:@"spantext"]) {
            NSLog(@"%@", [spanNode rawContents]); //Answer to second question
        }
    }
}
@end

使い方

HTMLSample *html = [[HTMLSample alloc] init];
[html sampleParse];