Это для 2,8.
Типичный способ обработки событий - использовать оператор сопоставления. В моем случае мне всегда приходилось хранить родителей при обработке элементов (например, чтобы узнать, в каком теге находится текст):
import scala.xml.pull._
import scala.io.Source
import scala.collection.mutable.Stack
val src = Source.fromString(xml)
val er = new XMLEventReader(src)
val stack = Stack[XMLEvent]()
def iprintln(s:String) = println((" " * stack.size) + s.trim)
while (er.hasNext) {
er.next match {
case x @ EvElemStart(_, label, _, _) =>
stack push x
iprintln("got <" + label + " ...>")
case EvElemEnd(_, label) =>
iprintln("got </" + label + ">")
stack pop;
case EvText(text) =>
iprintln(text)
case EvEntityRef(entity) =>
iprintln(entity)
case _ => // ignore everything else
}
}
Поскольку сущности - это события, вам, вероятно, потребуется преобразовать их в текст и объединить их с окружающим текстом.
В приведенном выше примере я использовал только метку, но вы также можете использовать EvElemStart(pre, label, attrs, scope)
, чтобы извлечь больше материала, и вы можете добавить if
охранник для соответствия сложным условиям.
Также, если вы используете 2.7.x, я не знаю, был ли http://lampsvn.epfl.ch/trac/scala/ticket/2583 перенесен обратно, поэтому у вас могут возникнуть проблемы при обработке текста с сущностями.
Более конкретно, просто для краткости и краткости (хотя я бы не назвал это Scala way ):
class Message() {
var to:String = _
var from:String = _
override def toString(): String =
"from %s to %s".format(from, to)
}
var message:Message = _
var sb:StringBuilder = _
while (er.hasNext) {
er.next match {
case x @ EvElemStart(_, "message", _, _) =>
message = new Message
case x @ EvElemStart(_, label, _, _) if
List("to", "from") contains label =>
sb = new StringBuilder
case EvElemEnd(_, "to") =>
message.to = sb.toString
case EvElemEnd(_, "from") =>
message.from = sb.toString
sb = new StringBuilder
case EvElemEnd(_, "message") =>
println(message)
case EvText(text) if sb != null =>
sb ++= text
case EvEntityRef(entity) =>
sb ++= unquote(entity) // todo
case _ => // ignore everything else
}
}