com.gitlab.mvysny.konsumexml.stax.JavaxXmlStreamStaxParser.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of konsume-xml Show documentation
Show all versions of konsume-xml Show documentation
Konsume-XML: A simple functional XML parser with no annotations
package com.gitlab.mvysny.konsumexml.stax
import java.io.InputStream
import javax.xml.XMLConstants
import javax.xml.namespace.QName
import javax.xml.stream.XMLInputFactory
import javax.xml.stream.XMLStreamReader
/**
* This parser uses the [XMLStreamReader] which is present in every JDK however it is not present in any Android.
*/
class JavaxXmlStreamStaxParser(val r: XMLStreamReader) : StaxParser {
override fun next() {
r.next()
}
override val location: Location
get() = r.location.let { Location(it.lineNumber, it.columnNumber, it.characterOffset, it.publicId, it.systemId) }
override val eventType: StaxEventType
get() = types[r.eventType - 1]
override val elementName: QName
get() = r.name
companion object {
private val types = listOf(StaxEventType.StartElement, StaxEventType.EndElement, StaxEventType.ProcessingInstruction,
StaxEventType.Characters, StaxEventType.Comment, StaxEventType.Space, StaxEventType.StartDocument,
StaxEventType.EndDocument, StaxEventType.EntityReference, StaxEventType.Attribute, StaxEventType.DTD,
StaxEventType.CData, StaxEventType.Namespace, StaxEventType.NotationDeclaration, StaxEventType.EntityDeclaration)
fun create(`in`: InputStream, systemId: String? = null): JavaxXmlStreamStaxParser {
val xmlInputFactory: XMLInputFactory = XMLInputFactory.newInstance()
val xmlStreamReader: XMLStreamReader = xmlInputFactory.createXMLStreamReader(systemId, `in`)
return JavaxXmlStreamStaxParser(xmlStreamReader)
}
}
private fun QName.hotfixRetardedAndroid(): QName {
if (localPart.startsWith("xml:")) {
// yes, Android Studio JVM will happily return attribute with localname "xml:lang" and empty namespace even though
// it should process namespaces BY DEFAULT
return QName(XMLConstants.XML_NS_URI, localPart.removePrefix("xml:"))
}
return this
}
override fun getAttributeName(index: Int): QName = r.getAttributeName(index).hotfixRetardedAndroid()
override val attributeCount: Int
get() = r.attributeCount
override fun getAttributeValue(namespaceURI: String, localName: String): String? = r.getAttributeValue(namespaceURI, localName)
override val text: String
get() = r.text
override fun close() {
r.close()
}
override fun hasNext(): Boolean = r.hasNext()
}