LoginSignup
39
38

More than 5 years have passed since last update.

軽くて、素早くて、 Swift の XML/HTML パーサー

Last updated at Posted at 2015-10-02

Fuzi

私が作ったXML/HTML パーサーFuziがSwiftSandbox Issue 9に当選しましたw

Update: 2016/09/24, FuziがFirefox for iOSプロジェクトに採用されました

Fuzi は Mattt Thompson氏の Ono(斧) に参照し Swift 言語で実装した XML/HTML パーサーです。[ドキュメント]

よろしければ、どうぞお使いくださ(CocoaPods, Carthage対応あり)

日本語のREADMEもあります https://github.com/cezheng/Fuzi/blob/master/README-ja.md

用例

XML

import Fuzi

let xml = "..."
do {
  // if encoding is omitted, it defaults to NSUTF8StringEncoding
  let doc = try XMLDocument(string: xml, encoding: NSUTF8StringEncoding)
  if let root = document.root {
    print(root.tag)

    // define a prefix for a namespace
    document.definePrefix("atom", defaultNamespace: "http://www.w3.org/2005/Atom")

    // get first child element with given tag in namespace(optional)
    print(root.firstChild(tag: "title", inNamespace: "atom")

    // iterate through all children
    for element in root.children {
      print("\(index) \(element.tag): \(element.attributes)")
    }
  }
  // you can also use CSS selector against XMLDocument when you feels it makes sense
} catch let error as XMLError {
  switch error {
  case .NoError: print("wth this should not appear")
  case .ParserFailure, .InvalidData: print(error)
  case .LibXMLError(let code, let message):
    print("libxml error code: \(code), message: \(message)")
  }
}

HTML

HTMLDocumentXMLDocument サブクラス。

import Fuzi

let html = "<html>...</html>"
do {
  // if encoding is omitted, it defaults to NSUTF8StringEncoding
  let doc = try HTMLDocument(string: html, encoding: NSUTF8StringEncoding)

  // CSS queries
  if let elementById = doc.css("#id") {
    print(elementById.stringValue)
  }
  for link in doc.css("a, link") {
      print(link.rawXML)
      print(link["href"]
  }

  // XPath queries
  if let title = doc.firstChild(xpath: "//head/title") {
    print(title.stringValue)
  }
  for paragraph in doc.xpath(".//body/descendant::p") {
    print(meta["class"])
  }

  // Evaluate XPath functions
  if let result = doc.eval(xpath: "count(/*/a)") {
    print("anchor count : \(result.doubleValue)")
  }
} catch let error {
  print(error)
}

エラー処理なんて、どうでもいい場合

import Fuzi

let xml = "..."

// Don't show me the errors, just don't crash
if let doc1 = try? XMLDocument(string: xml) {
  //...
}

let html = "<html>...</html>"

// I'm sure this won't crash
let doc2 = try! HTMLDocument(string: html)
//...

Onoからの移行?

下記2つのサンプルコードを見たら、OnoFuziの違いをわかる。

Onoサンプル

Fuziサンプル

もっと詳しい情報はgithubのREADMEをご覧ください。

39
38
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
39
38