All Downloads are FREE. Search and download functionalities are using the official Maven repository.

.circumflex-xml.2.3.source-code.xml.scala Maven / Gradle / Ivy

package ru.circumflex
package xml

import java.io._
import javax.xml.stream._
import collection.Iterator

// Homegrown minimalistic XML (de)serialization library

object xml extends XMLStreamConstants {

  val xmlif: XMLInputFactory = {
    val fac = XMLInputFactory.newFactory
    fac.setProperty("javax.xml.stream.isValidating", false)
    fac.setProperty("javax.xml.stream.isNamespaceAware", false)
    fac.setProperty("javax.xml.stream.isNamespaceAware", false)
    fac.setProperty("javax.xml.stream.isCoalescing", true)
    fac.setProperty("javax.xml.stream.isReplacingEntityReferences", true)
    fac
  }

  def parseStream(in: InputStream)(block: TagIterator => Any) {
    val xmlr = xmlif.createXMLStreamReader(in)
    val it = new TagIterator(xmlr)
    try {
      block(it)
    } finally {
      xmlr.close()
      in.close()
    }
  }

  def parse(file: File)(block: TagIterator => Any) {
    if (!file.isFile) {
      XML_LOG.warn("File " + file.getAbsoluteFile + " does not exist.")
      return
    }
    val is = new FileInputStream(file)
    parseStream(is)(block)
  }

  def parseString(string: String)(block: TagIterator => Any) {
    val is = new ByteArrayInputStream(string.getBytes("UTF-8"))
    parseStream(is)(block)
  }

}

class TagIterator(val reader: XMLStreamReader) extends Iterator[XmlTag] {
  protected var currentElem: Option[XmlTag] = None
  protected var lastElem: Option[XmlTag] = None

  def current: XmlTag = currentElem.getOrElse(
    throw new IllegalStateException("No current element in TagIterator."))

  def next(): XmlTag = lastElem match {
    case Some(e) =>
      currentElem = lastElem
      lastElem = None
      e
    case None =>
      if (hasNext) next()
      else throw new IndexOutOfBoundsException("No more elements in TagIterator.")
  }

  def hasNext: Boolean = lastElem match {
    case Some(e) => true
    case None if (reader.hasNext) =>
      val e = reader.next
      if (e == XMLStreamConstants.START_ELEMENT) {
        lastElem = Some(StartTag(reader.getLocalName))
        true
      } else if (e == XMLStreamConstants.END_ELEMENT) {
        lastElem = Some(EndTag(reader.getLocalName))
        true
      } else hasNext
    case None => false
  }

  def text: String = {
    currentElem = lastElem
    lastElem = None
    reader.getElementText
  }

  def attr(name: String): Option[String] = {
    val a = reader.getAttributeValue(null, name)
    if (a == null) None
    else Some(a)
  }

  override def toString() = ""
}

trait XmlTag {
  def name: String
}

case class StartTag(name: String) extends XmlTag
case class EndTag(name: String) extends XmlTag




© 2015 - 2024 Weber Informatics LLC | Privacy Policy