HTMLパーサ評価用のソースコード
org.htmlparser.saxのバージョンは2.0を使用。
http://htmlparser.sourceforge.net/
- HTMLファイルの読み込みは、FileInputStreamを使うので、コードセットを指定できない。
文字化けの原因となりえる。 - SAXのハンドラはorg.xml.sax.helpers.DefaultHandlerの標準仕様
- コメントタグの内容は出力できる。
- エラーハンドラがあるので、エラーはここから出力できる。
- 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) } }