XMLStream Reader Scala - END_DOCUMENT 的正确处理

XMLStream Reader Scala - Proper Handle of END_DOCUMENT

我其实是在重构一个现有的大型软件,从XMLEventReader切换到 XMLStreamReader 出于内存效率目的。

考虑以下函数定义,该函数当前只读取 XML 事件并打印它们:

def evalStreamReader(source: StreamSource): Unit

    val StreamReader = XMLInputFactory.newInstance().createXMLStreamReader(source)
    while (StreamReader.hasNext) {
      val eventType = StreamReader.getEventType
      eventType match {
        case 1 => println("Start Element " + eventType + " : " + StreamReader.getLocalName)
        case 2 => println("End Element " + eventType + " : " + StreamReader.getLocalName)
        case 4 => println("Characters " + eventType + " : " + StreamReader.getText)
        case 7 => println("Start Document " + eventType)
        case 8 => println("End Document: " + eventType)

      }
      StreamReader.next()
    }
}

和简单的 XML 文件:

<a>
  <c></c>
</a>

输出将是:

Start Document 7
Start Element 1 : a
Characters 4 : 
  
Start Element 1 : c
End Element 2 : c
Characters 4 : 

End Element 2 : a

我是否可以在 While condition/case 匹配内处理事件 END_DOCUMENT separately/correctly,而不是在循环外?我尝试了很多条件 do while 但没有成功。

想法是 StreamReader.next() 将在 END_DOCUMENT 事件中切换光标,而 hasNext 将 return 根据其在 API 中的定义为 false:

boolean hasNext()
         throws XMLStreamException
Returns true if there are more parsing events and false if there are no more events. 
This method will return false if the current state of the XMLStreamReader is END_DOCUMENT

一个简单的非惯用方法示例:

def evalStreamReader(source: StreamSource): Unit = {
  val streamReader: XMLStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(source)
  var finished: Boolean = false

  do {
    val eventType = streamReader.getEventType

    if (eventType != 8) {
      eventType match {
        case 1 => println("Start Element " + eventType + " : " + streamReader.getLocalName)
        case 2 => println("End Element " + eventType + " : " + streamReader.getLocalName)
        case 4 => println("Characters " + eventType + " : " + streamReader.getText)
        case 7 => println("Start Document " + eventType)
      }
      streamReader.next()
    } else {
      println("End Document: " + eventType)
      finished = true
    }
  } while(!finished)
  streamReader.close()
}

它会输出:

Start Document 7
Start Element 1 : a
Characters 4 : 
  
Start Element 1 : c
End Element 2 : c
Characters 4 : 

End Element 2 : a
End Document: 8

基本上您需要将流控制与 reader 分开。