Skip to content

Instantly share code, notes, and snippets.

@tototoshi
Created December 31, 2011 03:59
Show Gist options
  • Save tototoshi/1542812 to your computer and use it in GitHub Desktop.
Save tototoshi/1542812 to your computer and use it in GitHub Desktop.
ScalaでjQueryっぽいこと
import scala.xml._
import scala.util.parsing.combinator._
trait SelectorParser extends RegexParsers {
val html: NodeSeq
def tagSelector(tag: String)(filter: NodeSeq => Boolean): NodeSeq = html \\ tag filter filter
def idFilter(id: String): NodeSeq => Boolean = (n: NodeSeq) => (n \ "@id" text) == id
def classFilter(cls: String): NodeSeq => Boolean = (n: NodeSeq) => (n \ "@class" text) == cls
def idPrefix = "#"
def classPrefix = "."
def token = rep1("""[a-zA-Z-_:]""".r) ^^ { _.mkString }
def tag = token ^^ tagSelector
def id = idPrefix ~> token ^^ idFilter
def cls = classPrefix ~> token ^^ classFilter
def attr = id | cls
def selector = opt(tag) ~ opt(attr) ^^ {
case Some(t) ~ Some(a) => t(a)
case Some(t) ~ None => t(_ => true)
case _ => NodeSeq.Empty
}
def parse(in: String) = parseAll(selector, in) match {
case Success(res, _) => res
case _ => NodeSeq.Empty
}
}
class SQuery(val html: NodeSeq) extends SelectorParser {
def apply(selector: String): NodeSeq = parse(selector)
}
object Main {
val html =
<html>
<head>
<title>
</title>
</head>
<body>
<div id="container">
<div class="contents">
<span id="hello">Hello</span>
</div>
</div>
</body>
</html>
def main(args: Array[String]): Unit = {
val $ = new SQuery(html)
$("div") foreach { x =>
println(x)
println()
}
/* result:
<div id="container">
<div class="contents">
<span id="hello">Hello</span>
</div>
</div>
<div class="contents">
<span id="hello">Hello</span>
</div>
*/
println($("div.contents"))
/* result:
<div class="contents">
<span id="hello">Hello</span>
</div>
*/
println($("span#hello").text)
/* result:
Hello
*/
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment