使用XMLEventReader时如何检测XML错误?

时间:2012-07-27 05:52:08

标签: xml scala

scala.xml.pull.XMLEventReader的文档提到它可以用作Iterator[XMLEvent]。但是,这样做时,XML错误会导致方法调用无法终止。例如:

scala> new xml.pull.XMLEventReader(io.Source.fromString("<a><b></a>")).toArray
Exception in thread "XMLEventReader" scala.xml.parsing.FatalError: expected closing tag of b
    at scala.xml.parsing.MarkupParser$class.errorNoEnd(MarkupParser.scala:41)
    at scala.xml.pull.XMLEventReader$Parser.errorNoEnd(XMLEventReader.scala:56)
    at scala.xml.parsing.MarkupParserCommon$class.xEndTag(MarkupParserCommon.scala:93)
    at scala.xml.pull.XMLEventReader$Parser.xEndTag(XMLEventReader.scala:56)
    at scala.xml.parsing.MarkupParser$class.element1(MarkupParser.scala:543)
    at scala.xml.pull.XMLEventReader$Parser.element1(XMLEventReader.scala:56)
    at scala.xml.parsing.MarkupParser$class.content1(MarkupParser.scala:396)
    at scala.xml.pull.XMLEventReader$Parser.content1(XMLEventReader.scala:56)
    at scala.xml.parsing.MarkupParser$class.content(MarkupParser.scala:417)
    at scala.xml.pull.XMLEventReader$Parser.content(XMLEventReader.scala:56)
    at scala.xml.parsing.MarkupParser$class.element1(MarkupParser.scala:542)
    at scala.xml.pull.XMLEventReader$Parser.element1(XMLEventReader.scala:56)
    at scala.xml.parsing.MarkupParser$class.content1(MarkupParser.scala:396)
    at scala.xml.pull.XMLEventReader$Parser.content1(XMLEventReader.scala:56)
    at scala.xml.parsing.MarkupParser$class.document(MarkupParser.scala:216)
    at scala.xml.pull.XMLEventReader$Parser.document(XMLEventReader.scala:56)
    at scala.xml.pull.XMLEventReader$Parser$$anonfun$run$1.apply(XMLEventReader.scala:90)
    at scala.xml.pull.XMLEventReader$Parser$$anonfun$run$1.apply(XMLEventReader.scala:90)
    at scala.xml.pull.ProducerConsumerIterator$class.interruptibly(XMLEventReader.scala:113)
    at scala.xml.pull.XMLEventReader.interruptibly(XMLEventReader.scala:26)
    at scala.xml.pull.XMLEventReader$Parser.run(XMLEventReader.scala:90)
    at java.lang.Thread.run(Thread.java:680)

此调用永远不会终止。我们在这里看到打印了解析异常,但它似乎不会中断对toArray的调用。这似乎是因为实际的解析发生在一个单独的线程中,它终止了,但是错误永远不会报告给调用线程(这是described in the issue SI-4267)。是否有可能以某种方式在调用线程上重新引发这些异常?这个类是否打算使用,还是我应该使用另一个pull解析器?

2 个答案:

答案 0 :(得分:1)

如果您正在寻找拉解析和Scala,您应该结帐Scales Xml

特别是对于这种情况,pull解析由实际的pull解析器(jdk stax)驱动,并且可以插入实际使用的XMLInputFactory,允许您根据stax标准API自定义错误处理或文档处理。

再加上Iterator和Iteratee解析的能力,你在处理文档方面有很大的灵活性。

下一个版本0.5还将尝试使用Aalto XML来提供完全异步处理。

您的实际示例转换为:

import scales.xml._
import ScalesXml._

try{
  val s = pullXml(new java.io.StringReader("<a><b></a>")).toArray
} finally {
  println("Same thread")
}

并运行为(保存在experiment.scalaScript中并通过repl加载):

scala> :load .\experiments.scalaScript
Loading .\experiments.scalaScript...
import scales.xml._
import ScalesXml._
Same thread
javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,9]
Message: The element type "b" must be terminated by the matching end-tag "</b>".
        at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:594)

有关拉解析的更多示例,请参阅here

答案 1 :(得分:0)

我也遇到过那个;那里有一个补丁版本(在我自己的代码库中找不到链接),我们用了一段时间来解决问题 - 然后完全抛弃它。

相关问题