com.gitlab.mvysny.konsumexml.KonsumerUtils.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
The newest version!
package com.gitlab.mvysny.konsumexml
import com.gitlab.mvysny.konsumexml.stax.StaxParser
import com.gitlab.mvysny.konsumexml.stax.StaxParserFactory
import java.io.File
import java.io.InputStream
/**
* Parses this String as XML.
*/
public fun String.konsumeXml(): Konsumer = byteInputStream().konsumeXml()
/**
* Parses this input stream as XML. Don't forget to close returned [Konsumer] - that will also close this input stream.
*
* Uses [StaxParser] to read XML contents; see [StaxParserFactory] on details of how the parser is produced.
*/
public fun InputStream.konsumeXml(systemId: String? = null): Konsumer {
val parser: StaxParser = StaxParserFactory.create(this, systemId)
return Konsumer(StaxReader(parser, this), null, KonsumerSettings())
}
/**
* Parses this input stream as XML. It's important to close returned [Konsumer]:
* ```kotlin
* File("in.xml").konsumeXml().use { k ->
* k.child("root") {}
* }
* ```
*
* Uses [StaxParser] to read XML contents; see [StaxParserFactory] on details of how the parser is produced.
*/
public fun File.konsumeXml(): Konsumer = inputStream().andTry { it.buffered().konsumeXml(absolutePath) }
/**
* Consumes all of the remaining child elements of given [name]; automatically skips other elements. Doesn't skip
* over text contents - the text contents must be consumed by using the [Konsumer.text] function.
*
* WARNING: This function is dangerous in a way that it will silently throw away all elements that are not listed as
* parameters of the function.
* @param block called for every element with given [name]
*/
@KonsumerDsl
public fun Konsumer.allChildrenAutoIgnore(name: String, block: Konsumer.() -> Unit) {
allChildrenAutoIgnore(Names.of(name), block)
}
/**
* Consumes all of the remaining child elements of given [names]; automatically skips other elements. Doesn't skip
* over text contents - the text contents must be consumed by using the [Konsumer.text] function.
*
* WARNING: This function will silently throw away all elements that are not listed as
* parameters of the function, effectively disabling validation for those elements.
* @param block called for every element with given [names]
*/
@KonsumerDsl
public fun Konsumer.allChildrenAutoIgnore(names: Names, block: Konsumer.() -> Unit) {
children(anyName) {
if (names.accepts(elementName!!)) block() else skipContents()
}
}
/**
* Reads all follow-up text of this element. When a child element is encountered,
* the function will automatically read its text recursively.
* Perfect for reading text contents of this and all child elements,
* e.g. when parsing a text article.
*
* It's not possible to retrieve the child elements once the parsing is done.
* If you need this kind of functionality, just copy this function's sources
* and modify them accordingly.
*
* WARNING: This function will silently throw away all encountered nested elements,
* effectively disabling validation for those elements.
* @param whitespace the way to process whitespaces. Warning: contrary to [Konsumer.text]
* this defaults to [Whitespace.collapse_no_trim], in order to parse
* `hello world again
` as `hello world again` (preserve spaces).
*/
public fun Konsumer.textRecursively(whitespace: Whitespace = Whitespace.collapse_no_trim): String {
val sb = StringBuilder()
fun Konsumer.textRecursivelyInt() {
while (!isFinished) {
sb.append(text(whitespace, false))
if (!isFinished) {
childOrNull(anyName) {
textRecursivelyInt()
}
}
}
}
textRecursivelyInt()
return sb.toString()
}