Groovy - NekoHTML Sax parser - PullRequest
       5

Groovy - NekoHTML Sax parser

4 голосов
/ 16 августа 2011

У меня проблемы с парсером NekoHTML.Он отлично работает с URL-адресами, но когда я хочу протестировать простой XML-тест, он не читает его правильно.

Вот как я это заявляю:

def createAndSetParser() { 
  SAXParser parser = new SAXParser()  //Default Sax NekoHTML parser 
  def charset = "Windows-1252"  // The encoding of the page 
  def tagFormat = "upper"    // Ensures all the tags and consistently written, by putting all of them in upper-case. We can choose "lower", "upper" of "match" 
  def attrFormat = "lower"  // Same thing for attributes. We can choose "upper", "lower" or "match" 

  Purifier purifier = new Purifier()     //Creating a purifier, in order to clean the incoming HTML 
  XMLDocumentFilter[] filter = [purifier] //Creating a filter, and adding the purifier to this filter. (NekoHTML feature) 

  parser.setProperty("http://cyberneko.org/html/properties/filters", filter) 
  parser.setProperty("http://cyberneko.org/html/properties/default-encoding", charset) 
  parser.setProperty("http://cyberneko.org/html/properties/names/elems", tagFormat) 
  parser.setProperty("http://cyberneko.org/html/properties/names/attrs", attrFormat) 
  parser.setFeature("http://cyberneko.org/html/features/scanner/ignore-specified-charset", true)    // Forces the parser to use the charset we provided to him. 
  parser.setFeature("http://cyberneko.org/html/features/override-doctype", false)    // To let the Doctype as it is. 
  parser.setFeature("http://cyberneko.org/html/features/override-namespaces", false)     // To make sure no namespace is added or overridden. 
  parser.setFeature("http://cyberneko.org/html/features/balance-tags", true) 

  return new XmlSlurper(parser)   // A groovy parser that does not download the all tree structure, but rather supply only the information it is asked for. 
} 

Опять же, он очень хорошо работает, когда я использую его на веб-сайтах.Любое предположение, почему я не могу сделать это на простых образцах текста XML?

Любая помощь очень ценится:)

1 Ответ

2 голосов
/ 21 декабря 2011

Я сделал ваш сценарий исполняемым на Groovy Console, чтобы легко его опробовать, используя Grape для извлечения необходимой библиотеки NekoHTML из центрального репозитория Maven.

@Grapes(
  @Grab(group='net.sourceforge.nekohtml', module='nekohtml', version='1.9.15')
)

import groovy.xml.StreamingMarkupBuilder
import org.apache.xerces.xni.parser.XMLDocumentFilter
import org.cyberneko.html.parsers.SAXParser
import org.cyberneko.html.filters.Purifier

def createAndSetParser() { 
  SAXParser parser = new SAXParser()
  parser.setProperty("http://cyberneko.org/html/properties/filters", [new Purifier()] as XMLDocumentFilter[])
  parser.setProperty("http://cyberneko.org/html/properties/default-encoding", "Windows-1252")
  parser.setProperty("http://cyberneko.org/html/properties/names/elems", "upper")
  parser.setProperty("http://cyberneko.org/html/properties/names/attrs", "lower")
  parser.setFeature("http://cyberneko.org/html/features/scanner/ignore-specified-charset", true)
  parser.setFeature("http://cyberneko.org/html/features/override-doctype", false)
  parser.setFeature("http://cyberneko.org/html/features/override-namespaces", false)
  parser.setFeature("http://cyberneko.org/html/features/balance-tags", true) 
  return new XmlSlurper(parser)
} 

def printResult(def gPathResult) {
  println new StreamingMarkupBuilder().bind { out << gPathResult }
} 

def parser = createAndSetParser()

printResult parser.parseText('<html><body>Hello World</body></html>')
printResult parser.parseText('<house><room>bedroom</room><room>kitchen</room></house>')

При выполнении таким способом результат двух printResult -статементов выглядит, как показано ниже, и может объяснить ваши проблемы при разборе строки XML, поскольку она заключена в теги <html><body>...</body></html> и теряет корневой тег с именем <house/>:

<HTML><tag0:HEAD xmlns:tag0='http://www.w3.org/1999/xhtml'></tag0:HEAD><BODY>Hello World</BODY></HTML>
<HTML><BODY><ROOM>bedroom</ROOM><ROOM>kitchen</ROOM></BODY></HTML>

Все это вызвано функцией http://cyberneko.org/html/features/balance-tags, которую вы включили в своем скрипте. Если я отключу эту функцию (для нее должно быть явно установлено значение false, поскольку по умолчанию она равна true), результаты будут выглядеть следующим образом:

<HTML><BODY>Hello World</BODY></HTML>
<HOUSE><ROOM>bedroom</ROOM><ROOM>kitchen</ROOM></HOUSE>
...