どうすればいいのか分かりませんでしたが、Pangeashowed me the wayです。最初に、場所を処理するための形質を作成してみましょう:
import org.xml.sax.{helpers, Locator, SAXParseException}
trait WithLocation extends helpers.DefaultHandler {
var locator: org.xml.sax.Locator = _
def printLocation(msg: String) {
println("%s at line %d, column %d" format (msg, locator.getLineNumber, locator.getColumnNumber))
}
// Get location
abstract override def setDocumentLocator(locator: Locator) {
this.locator = locator
super.setDocumentLocator(locator)
}
// Display location messages
abstract override def warning(e: SAXParseException) {
printLocation("warning")
super.warning(e)
}
abstract override def error(e: SAXParseException) {
printLocation("error")
super.error(e)
}
abstract override def fatalError(e: SAXParseException) {
printLocation("fatal error")
super.fatalError(e)
}
}
次は、私たちの形質を含めるようにXMLLoader
のadapter
をオーバーライドする当社独自のローダーを作成してみましょう:
import scala.xml.{factory, parsing, Elem}
object MyLoader extends factory.XMLLoader[Elem] {
override def adapter = new parsing.NoBindingFactoryAdapter with WithLocation
}
をそして、それはそれで全部です!オブジェクトXML
は、XMLLoader
にほとんど追加しません - 基本的にsave
メソッドです。完全な置き換えが必要な場合は、ソースコードを参照してください。しかし、これはあなたがScalaは、既にエラーを生産する形質を持っているので、このすべてを自分で処理したい場合にのみ、次のとおりです。
object MyLoader extends factory.XMLLoader[Elem] {
override def adapter = new parsing.NoBindingFactoryAdapter with parsing.ConsoleErrorHandler
}
ConsoleErrorHandler
形質は仕方によって、例外からその行と番号情報を抽出します。私たちの目的のために、私たちは例外の外の場所も必要とします(私は仮定しています)。
ノードの作成自体を変更するには、scala.xml.factory.FactoryAdapter
抽象メソッドを見てください。 createNode
に解決しましたが、NoBindingFactoryAdapter
レベルでオーバーライドしています。これはNode
の代わりにElem
を返すため、属性を追加できます。だから、:
import org.xml.sax.Locator
import scala.xml._
import parsing.NoBindingFactoryAdapter
trait WithLocation extends NoBindingFactoryAdapter {
var locator: org.xml.sax.Locator = _
// Get location
abstract override def setDocumentLocator(locator: Locator) {
this.locator = locator
super.setDocumentLocator(locator)
}
abstract override def createNode(pre: String, label: String, attrs: MetaData, scope: NamespaceBinding, children: List[Node]): Elem = (
super.createNode(pre, label, attrs, scope, children)
% Attribute("line", Text(locator.getLineNumber.toString), Null)
% Attribute("column", Text(locator.getColumnNumber.toString), Null)
)
}
object MyLoader extends factory.XMLLoader[Elem] {
// Keeping ConsoleErrorHandler for good measure
override def adapter = new parsing.NoBindingFactoryAdapter with parsing.ConsoleErrorHandler with WithLocation
}
結果:それは最後の位置、終了タグの1つを得たことを
scala> MyLoader.loadString("<a><b/></a>")
res4: scala.xml.Elem = <a line="1" column="12"><b line="1" column="8"></b></a>
注意。これは、startElement
をオーバーライドして各要素がスタック内で開始された場所を把握し、このスタックからvar
によって使用されるになるようにendElement
をポップすることで改善できます。
良い質問。私は多くのことを学びました! :-)
とても遅れて申し訳ありません。あなたの答えは素晴らしいです。私は本当の解決策を期待していませんでしたが、あなたは実際に解決策を見つけました。どうもありがとう! – Madoc
あなたや他人だけが開始行番号を取得する方法を示すことができます:P – Jus12