我正在尝试加载有效的HTML以便在Scala中进行处理。似乎转换为xml将是一个很好的起点。对于这样做有点争议的scala.xml.Xhtml Scala core library看起来非常好的代码。基本上它应该需要'修复'在HTML中有效但不是有效的xml的标签,从而阻止文件有效xhtml,而且还要多一点。这是来自那里的代码:
def toXhtml(
x: Node,
pscope: NamespaceBinding = TopScope,
sb: StringBuilder = new StringBuilder,
stripComments: Boolean = false,
decodeEntities: Boolean = false,
preserveWhitespace: Boolean = false,
minimizeTags: Boolean = true): Unit =
{
def decode(er: EntityRef) = XhtmlEntities.entMap.get(er.entityName) match {
case Some(chr) if chr.toInt >= 128 => sb.append(chr)
case _ => er.buildString(sb)
}
def shortForm =
minimizeTags &&
(x.child == null || x.child.length == 0) &&
(minimizableElements contains x.label)
x match {
case c: Comment => if (!stripComments) c buildString sb
case er: EntityRef if decodeEntities => decode(er)
case x: SpecialNode => x buildString sb
case g: Group =>
g.nodes foreach { toXhtml(_, x.scope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags) }
case _ =>
sb.append('<')
x.nameToString(sb)
if (x.attributes ne null) x.attributes.buildString(sb)
x.scope.buildString(sb, pscope)
if (shortForm) sb.append(" />")
else {
sb.append('>')
sequenceToXML(x.child, x.scope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags)
sb.append("</")
x.nameToString(sb)
sb.append('>')
}
}
}
似乎需要一些过分的毅力才能找到如何将该函数用于已使用scala.io.Source(fromFile)
获取的现有html文档。 Node
类型的含义在代码库中似乎有点elusive,或者我不确定如何从scala.io.Source的fromFile
收到的字符串到达可以被送入上面复制的函数toXhtml
。
The scaladoc for this function似乎没有多大澄清。
还有another related library,其中scaladoc只有很多条目。
如果有人能说出如何使用这个库将原始html字符串转换为'clean'xhtml,并且如何从the source code推导出来,我会很高兴,因为我的Scala可能不是我看到的那么好..
答案 0 :(得分:2)
您可以考虑使用jsoup,因为它擅长处理凌乱的真实HTML。它还可以基于允许标记的白名单来清理HTML。一个例子:
import org.jsoup.Jsoup
import org.jsoup.safety.Whitelist
import scala.collection.JavaConversions._
import scala.io.Source
object JsoupExample extends App {
val suspectHtml = Source.fromURL("http://en.wikipedia.org/wiki/Scala_(programming_language)").mkString
val cleanHtml = Jsoup.clean(suspectHtml, Whitelist.basic)
val doc = Jsoup.parse(cleanHtml)
doc.select("p").foreach(node => println(node.text))
}