Scala+DBMS+Web スカラ座の夜

2011年8月31日

HTML Parser 評価 org.htmlparser.sax

Filed under: Scala — admin @ 9:29 PM

HTMLパーサ評価用のソースコード

org.htmlparser.saxのバージョンは2.0を使用。
http://htmlparser.sourceforge.net/

  1. HTMLファイルの読み込みは、FileInputStreamを使うので、コードセットを指定できない。
    文字化けの原因となりえる。
  2. SAXのハンドラはorg.xml.sax.helpers.DefaultHandlerの標準仕様
  3. コメントタグの内容は出力できる。
  4. エラーハンドラがあるので、エラーはここから出力できる。
  5. 2.0では、STRONGタグやHTML5で追加されたタグをパースできない。CENTERタグ,FONTタグなども認識できないです。




と、1でコードセットを指定できないと書きましたが、InputSourceに対してsetEncoding関数でコード指定できます。


val input = new FileInputStream(htmlFile)
val inputSource = new InputSource(input)
inputSource.setEncoding("UTF-8")




htmlparser のソースコードに対して、定義されていないタグを処理できるように拡張する



評価用のソースコードは以下のとおり。

setEncoding関数でコード指定を追加してあります。


package ews.servlet.sp

import java.io._
import javax.servlet.http._
import org.xml.sax.{InputSource,ErrorHandler,Attributes,SAXException,SAXParseException}
import org.xml.sax.helpers.{DefaultHandler,XMLReaderFactory}
import org.htmlparser.sax._

class Htmlparse4Sp (request : HttpServletRequest, response : HttpServletResponse, htmlPath : String) extends TemplSp {
	var parsed:String = null	// 
	override def toString :String = parsed
	// replace HTML
	def html : String = {
		val htmlFile = new java.io.File(htmlPath)
		if(htmlFile.exists && htmlPath.toLowerCase.endsWith(".html")){
			println("Htmlparse4Sp html ---")
			try {
				val input = new FileInputStream(htmlFile)	// open HTML file
				val inputSource = new InputSource(input)
				inputSource.setEncoding("UTF-8")
				val cb = new ParserCallback4
				
				val r = XMLReaderFactory.createXMLReader("org.htmlparser.sax.XMLReader")
				r.setContentHandler(cb)
				r.parse(inputSource)
				println("Htmlparse4Sp parse---")

				input.close
				parsed = cb.toString
				return parsed
			} catch {
			  case e:IOException => {
				  println("Exception "+e.getMessage)
			  }
			}
		}
		null	// There is no file. 
	}
}

class ErrorHandler4 extends ErrorHandler {
		def warning(e:SAXParseException ) :Unit= {
			println("ERROR warning")
			throw new SAXException(e)
		}
		def error(e:SAXParseException) :Unit= {
			println("ERROR error")
			throw new SAXException(e)
		}
		def fatalError(e:SAXParseException) :Unit= {
			println("ERROR fatalError")
			throw new SAXException(e)
		}
		// default constructor
		def ErrorTestHandler :Unit= {
		}
}

ハンドラのソースコード

package ews.servlet.sp

import org.xml.sax._
import org.xml.sax.helpers.DefaultHandler

class ParserCallback4 extends DefaultHandler {
	var buf = new StringBuffer
	var locator:Locator = null
	override def toString :String = buf.toString
	override def setDocumentLocator (locator:Locator) :Unit=  {
	  println("setDocumentLocator")
		this.locator = locator
	}
	override def startDocument ():Unit= {	System.out.println("Start document");}
	override def endDocument():Unit= {	System.out.println("End document");}
	override def startElement ( uri:String,  name:String, qualifiedName:String , attrs:Attributes ):Unit={
		var buflocal = new StringBuffer
		buflocal.append("<"+name)
		for (idx <- 0 to attrs.getLength - 1){
			val attributeType = attrs.getType(idx)
			val attrLocalName = attrs.getLocalName(idx) 
			val attrName = attrs.getQName(idx)
			val attrValue = attrs.getValue(idx)
			if(attrLocalName.length > 0 && !"#text".equals(attrLocalName)){
				buflocal.append(" " + attrLocalName + "=\"" + attrValue + "\"")
			}
		}
		buflocal.append(">")
		buf.append(buflocal)
	}
	override def endElement (uri:String ,  name:String, qualifiedName:String):Unit={
		buf.append("</"+name+">")
	}
	override def characters(ch:Array[Char],start:Int,length:Int) : Unit = {
		var str:String = ""
		for(i <- start to length+start-1){
			str += ch(i)
		}
		buf.append(str)
	}
	override def unparsedEntityDecl(name:String,publicId:String,systemId:String,notationName:String) : Unit = {
		println("unparsedEntityDecl name="+name + " publicId=" + publicId + " systemId="+systemId + " notationName=" + notationName)
	}
	override def startPrefixMapping(prefix:String , uri:String ) : Unit = {
		println("startPrefixMapping prefix="+prefix + " uri=" + uri)
	}
	override def endPrefixMapping(prefix:String) : Unit = {
		println("endPrefixMapping prefix="+prefix)
	}
	override def processingInstruction(target:String, data:String) : Unit = {
		println("processingInstruction target="+target + " data="+data)
	}
	override def skippedEntity(name:String) : Unit = {
		println("skippedEntity name="+name)
	}
}

コメントはまだありません »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

コメントを投稿するにはログインしてください。

Powered by WordPress