
scales.xml.trax.ScalesStreamReader.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scales-xml_2.11 Show documentation
Show all versions of scales-xml_2.11 Show documentation
An alternate Scala Xml processing library
The newest version!
package scales.xml.trax
import scales.xml._
import javax.xml.transform.stream._
import javax.xml.stream._
import javax.xml.namespace.{QName => JQName, NamespaceContext}
import ScalesXml._
/**
* The trax support, the stream reader in particular
* is aimed at allowing xlst transformations, a further
* serialization option and conversion to other DOMs
*/
/**
* Provides a stream reader interface for StAX.
*/
trait ScalesStreamReader extends XMLStreamReader {
import XMLStreamConstants._
protected val itr : Iterator[PullType]
protected var ev : PullType = _
protected var evType : Int = START_DOCUMENT
// have we fired the starting document?
protected var startedDoc = false
/**
* Take just the prolog and end misc
*/
protected val docLike : DocLike
lazy val prologItr = docLike.prolog.misc.iterator
lazy val endItr = docLike.end.misc.iterator
def setEv() {
// println("called with ev " + ev )
evType = ev.fold( _ match {
case _ : Elem => START_ELEMENT
case _ : Text => CHARACTERS
case _ : CData => CDATA
case _ : Comment => COMMENT
case _ : PI => PROCESSING_INSTRUCTION
} , _ => END_ELEMENT)
// println("set evType " + evType)
}
var doEndDoc = false
var shouldPop = false
var nc : TNC = EmptyNamespaceContext
/**
* Only usable when its an element of course
* We copy to an array for indexed access and keep
* using ev for map access
*/
protected var attribs : Array[Attribute] = _
def close() {}
def getAttributeCount() : Int = attribs.size
def getAttributeLocalName( index : Int ) : String = attribs(index).local
def getAttributeName( index : Int) : JQName = {
val att : QName = attribs(index)
att match {
case l : NoNamespaceQName => new JQName(l.local)
case u : UnprefixedQName => new JQName(u.namespace.uri, u.local)
case p : PrefixedQName => new JQName(p.namespace.uri, p.local, p.prefix.get)
}
}
def getAttributeNamespace( index : Int) : String = attribs(index).namespace.uri
def getAttributePrefix( index : Int) : String = attribs(index).prefix.getOrElse(null : String)
def getAttributeType( index : Int ) : String = null : String
def getAttributeValue( index : Int ) : String = attribs(index).value
def getAttributeValue(namespaceURI : String, localName : String) : String =
ev.left.get.asInstanceOf[Elem].attributes(Namespace(namespaceURI).apply(localName)).map(_.value).getOrElse(null : String)
def getCharacterEncodingScheme() : String = "UTF-16"
def getElementText() : String = {
if(getEventType() != XMLStreamConstants.START_ELEMENT) {
throw new XMLStreamException(
"parser must be on START_ELEMENT to read next text", getLocation());
}
var eventType = next();
var buf = new StringBuilder();
while(eventType != XMLStreamConstants.END_ELEMENT ) {
if(eventType == XMLStreamConstants.CHARACTERS
|| eventType == XMLStreamConstants.CDATA
|| eventType == XMLStreamConstants.SPACE
|| eventType == XMLStreamConstants.ENTITY_REFERENCE) {
buf.append(getText());
} else if(eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
|| eventType == XMLStreamConstants.COMMENT) {
// skipping
} else if(eventType == XMLStreamConstants.END_DOCUMENT) {
throw new XMLStreamException(
"unexpected end of document when reading element text content");
} else if(eventType == XMLStreamConstants.START_ELEMENT) {
throw new XMLStreamException(
"element text content may not contain START_ELEMENT", getLocation());
} else {
throw new XMLStreamException(
"Unexpected event type "+eventType, getLocation());
}
eventType = next();
}
buf.toString();
}
def getEncoding() : String = "UTF-16"
def getEventType() : Int = evType
/**
* Called for both start element and end element
*/
def elemName =
ev.fold(e => e.asInstanceOf[Elem].name,
ee => ee.name)
def getLocalName() : String = elemName.local
def getLocation() : Location = EmptyStreamLocation
def getName() : JQName =
elemName match {
case l : NoNamespaceQName => new JQName(l.local)
case u : UnprefixedQName => new JQName(u.namespace.uri, u.local)
case p : PrefixedQName => new JQName(p.namespace.uri, p.local, p.prefix.get)
}
def getNamespaceContext() : NamespaceContext = nc
def getNamespaceCount() : Int = nc.ns.size
def getNamespacePrefix(index : Int) : String = nc.ns(index)._1
def getNamespaceURI() : String = elemName.namespace.uri
def getNamespaceURI( index : Int ) : String = nc.ns(index)._2
def getNamespaceURI( prefix : String) : String = nc.getNamespaceURI(prefix)
def getPIData() : String = ev.left.get.asInstanceOf[PI].value
def getPITarget() : String = ev.left.get.asInstanceOf[PI].target
def getPrefix() : String = elemName.prefix.getOrElse("")//null : String)
def getProperty(name : String) : Object = null
def getText() : String = ev.left.get.asInstanceOf[XmlItem].value
def getTextCharacters() : Array[Char] = getText.toArray
def getTextCharacters(sourceStart : Int, target : Array[Char], targetStart : Int, length : Int) : Int = {
if (targetStart < 0 || targetStart > getTextLength())
throw new IndexOutOfBoundsException("TargetStart was out of bounds: "+targetStart+" textLength "+getTextLength())
if (length < 0 || (targetStart + length > getTextLength()))
throw new IndexOutOfBoundsException("TargetStart and Length was out of bounds: "+targetStart+" length "+length+" textLength "+getTextLength())
System.arraycopy(getTextCharacters(), sourceStart, target, targetStart, length)
length
}
def getTextLength() : Int = getText().size
def getTextStart() : Int = 0
def getVersion() : String = docLike.prolog.decl.version.version
def hasName() : Boolean = evType == START_ELEMENT || evType == END_ELEMENT
def hasNext() : Boolean = prologItr.hasNext || itr.hasNext || endItr.hasNext || doEndDoc
def hasText() : Boolean = evType == CDATA || evType == COMMENT || evType == CHARACTERS
def isAttributeSpecified(index : Int) : Boolean = false // can't specify this
def isCharacters() : Boolean = evType == CHARACTERS
def isEndElement() : Boolean = evType == END_ELEMENT
def isStandalone() : Boolean = standaloneSet
def isStartElement() : Boolean = evType == START_ELEMENT
def isWhiteSpace() : Boolean = getText.trim.size == 0
def doPop {
if (shouldPop) {
nc = nc.parent
shouldPop = false
}
}
def next() : Int = {
if (!startedDoc) {
startedDoc = true
return START_DOCUMENT
}
if (doEndDoc) {
doEndDoc = false
// println("doc end")
return END_DOCUMENT
}
if (prologItr.hasNext) {
ev = prologItr.next.fold(x=>x, y=>y)
} else if (itr.hasNext) {
ev = itr.next
} else {
ev = endItr.next.fold(x=>x, y=>y)
}
setEv
import NamespaceContextFunctions._
evType match {
case START_ELEMENT =>
// println(" se : "+ev)
val el = ev.left.get.asInstanceOf[Elem]
attribs = el.attributes.toArray
doPop
nc = newContext(nc, el)
case END_ELEMENT =>
// println(" ee : "+ ev)
shouldPop = true
case _ =>
// println(" item "+ev)
doPop
}
if (!itr.hasNext && !endItr.hasNext) {
doEndDoc = true
}
evType
}
// tough one as well, Skips any white space (isWhiteSpace() returns true), COMMENT, or PROCESSING_INSTRUCTION, until a START_ELEMENT or END_ELEMENT is reached.
def nextTag() : Int = {
var eventType = next()
while((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip whitespace
|| (eventType == XMLStreamConstants.CDATA && isWhiteSpace())
// skip whitespace
|| eventType == XMLStreamConstants.SPACE
|| eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
|| eventType == XMLStreamConstants.COMMENT
) {
eventType = next()
}
if (eventType != XMLStreamConstants.START_ELEMENT && eventType != XMLStreamConstants.END_ELEMENT) {
throw new XMLStreamException("expected start or end tag", getLocation())
}
eventType
}
def require(tipe : Int, namespaceURI : String , localName : String) {
if (evType != tipe)
throw new XMLStreamException("Type does not match", getLocation())
if (namespaceURI != null && namespaceURI != getNamespaceURI())
throw new XMLStreamException("Namespace does not match", getLocation())
if (localName != null && localName != getLocalName())
throw new XMLStreamException("LocalName does not match", getLocation())
}
def standaloneSet() : Boolean = docLike.prolog.decl.standalone
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy