Skip to content

Instantly share code, notes, and snippets.

@LouisCAD
Created May 24, 2021 21:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LouisCAD/579e84f21bfcd30a3c887b61bc560529 to your computer and use it in GitHub Desktop.
Save LouisCAD/579e84f21bfcd30a3c887b61bc560529 to your computer and use it in GitHub Desktop.
Kotlin extensions for javax.xml (package org.w3c.dom). Feel free to copy paste.
import org.w3c.dom.Document
import org.w3c.dom.Text
import java.io.StringWriter
import javax.xml.transform.OutputKeys
import javax.xml.transform.TransformerFactory
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult
fun Document.toText(): String {
val domSource = DOMSource(this)
val writer = StringWriter()
val streamResult = StreamResult(writer)
TransformerFactory.newInstance().newTransformer().also {
it.setOutputProperty(OutputKeys.INDENT, "yes")
it.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "")
}.transform(domSource, streamResult)
return writer.use { it.toString() }
}
fun Document.removeBlankNodes() {
val childNodes = documentElement.childNodes.asList()
var skipNextNode = false
//TODO: Make recursive.
childNodes.asReversed().forEach { node ->
if (skipNextNode.not()) {
val isNodeBlank = node is Text && node.wholeText.isBlank()
if (isNodeBlank) {
documentElement.removeChild(node)
skipNextNode = true
}
} else skipNextNode = false
}
}
import org.w3c.dom.Node
internal fun Node.insertChildAt(index: Int, newChild: Node) {
require(index >= 0)
require(index <= childNodes.length)
when (index) {
childNodes.length -> appendChild(newChild)
else -> insertBefore(newChild, childNodes.item(index))
}
}
internal fun Node.insertAfter(newChild: Node, refChild: Node) {
val refIndex = childNodes.asSequence().indexOf(refChild)
require(refIndex != -1)
insertChildAt(index = refIndex + 1, newChild = newChild)
}
internal fun Node.insertBeforeOrAtTop(newChild: Node, refChild: Node?) {
when (refChild) {
null -> insertChildAt(index = 0, newChild = newChild)
else -> insertBefore(newChild, refChild)
}
}
import org.w3c.dom.Node
import org.w3c.dom.NodeList
internal fun NodeList.asList(): List<Node> = List(length) { item(it) }
internal fun NodeList.asSequence(): Sequence<Node> = sequence {
for (i in 0 until length) yield(item(i))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment