HTMLパーサ評価用のソースコード
org.cyberneko.html.parsersのバージョンは1.9.15を使用。
http://nekohtml.sourceforge.net/index.html
- HTMLファイルの読み込みは、InputStreamReaderが使えるので、コードセットを指定することができる。
文字化けの原因を回避。 - SAXのハンドラはorg.xml.sax.helpers.DefaultHandlerの標準仕様
- オリジナルにあるコメントタグの内容は出力できない。
- エラーハンドラがあるので、エラーはここから出力できる。
- タグの出力は<BR>タグを<BR></BR>と出力するので修正。
HRタグも同様
IMGタグとINPUTタグのエンドタグは削除。 - ネストしたタグの解析処理に不具合があるようで、タグが不完全と判断して余分なタグを出力するため画面が乱れてしまう。
評価用のソースコードは以下のとおり。
package ews import java.io._ import javax.servlet.http._ import org.xml.sax.helpers._ import org.xml.sax.{InputSource,ErrorHandler,Attributes,SAXException,SAXParseException} import org.cyberneko.html.parsers._ class Htmlparse3Sp (request : HttpServletRequest, response : HttpServletResponse, htmlPath : String) extends TemplSp { var parsed:String = null // override def toString :String = parsed // cyberneko 1.9.15 def html : String = { val htmlFile = new java.io.File(htmlPath) if(htmlFile.exists && htmlPath.toLowerCase.endsWith(".html")){ var input:InputStreamReader = null try { input = new InputStreamReader (new FileInputStream(htmlFile), "UTF-8") // open HTML file val inputSource = new InputSource(input) val cb = new ParserCallback3 val r = new SAXParser r.setContentHandler(cb) r.setErrorHandler(new ErrorHandler3) r.parse(inputSource) parsed = cb.toString.replaceAll("<br></br>","<br>") .replaceAll("<hr></hr>","<hr>") .replaceAll("</input>","") .replaceAll("</img>","") return parsed } catch { case e:IOException => { println("Exception "+e.getMessage) } } finally { input.close } } null // There is no file. } } class ErrorHandler3 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 import org.xml.sax._ import org.xml.sax.helpers.DefaultHandler class ParserCallback3 extends DefaultHandler { var buf = new StringBuffer override def toString :String = buf.toString 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, qName:String , attrs:Attributes ):Unit={ var buflocal = new StringBuffer buflocal.append("<"+qName.toLowerCase) for (idx <- 0 to attrs.getLength - 1){ val attrName = attrs.getQName(idx) val attrValue = attrs.getValue(idx) buflocal.append(" " + attrName + "=\"" + attrValue + "\"") } buflocal.append(">") buf.append(buflocal) } override def endElement (uri:String , name:String, qName:String):Unit={ buf.append("</" + qName.toLowerCase + ">") } 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) } }