added helper methods for iterating through next/previous nodes or elements on the DOM

This commit is contained in:
James Strachan
2012-03-23 11:04:51 +00:00
parent b2dd4cd590
commit 19cdb782ac
3 changed files with 57 additions and 25 deletions
+41 -1
View File
@@ -1,6 +1,7 @@
package kotlin.dom
import kotlin.*
import kotlin.support.*
import kotlin.util.*
import java.util.*
import org.w3c.dom.*
@@ -190,6 +191,45 @@ fun Element.get(selector: String): List<Element> {
}
}
/** Returns an [[Iterator]] over the next siblings of this node */
fun Node.nextSiblings() : Iterator<Node> = NextSiblingIterator(this)
protected class NextSiblingIterator(var node: Node) : AbstractIterator<Node>() {
override fun computeNext(): Node? {
val next = node.getNextSibling()
if (next != null) {
node = next
return next
} else {
done()
return null
}
}
}
/** Returns an [[Iterator]] over the next siblings of this node */
fun Node.previousSiblings() : Iterator<Node> = PreviousSiblingIterator(this)
protected class PreviousSiblingIterator(var node: Node) : AbstractIterator<Node>() {
override fun computeNext(): Node? {
val next = node.getPreviousSibling()
if (next != null) {
node = next
return next
} else {
done()
return null
}
}
}
/** Returns an [[Iterator]] of all the next [[Element]] siblings */
fun Node.nextElements(): Iterator<Element> = nextSiblings().filterIs<Node, Element>()
/** Returns an [[Iterator]] of all the previous [[Element]] siblings */
fun Node.previousElements(): Iterator<Element> = previousSiblings().filterIs<Node, Element>()
/** Returns the attribute value or empty string if its not present */
inline fun Element.attribute(name: String): String {
return this.getAttribute(name) ?: ""
@@ -271,7 +311,7 @@ inline fun NodeList?.toElementList(): List<Element> {
fun NodeList?.toXmlString(xmlDeclaration: Boolean = false): String {
return if (this == null)
"" else {
this.toList().toXmlString(xmlDeclaration)
nodesToXmlString(this.toList(), xmlDeclaration)
}
}
+15 -23
View File
@@ -17,6 +17,7 @@ import javax.xml.transform.OutputKeys
import java.lang.Iterable
import java.util.List
import java.util.Collection
import java.io.Writer
/** Creates a new document with the given document builder*/
fun createDocument(builder: DocumentBuilder): Document {
@@ -39,35 +40,26 @@ fun createTransformer(source: Source? = null, factory: TransformerFactory = Tran
}
/** Converts the node to an XML String */
fun Node.toXmlString(xmlDeclaration: Boolean = this is Document): String {
return nodeToXmlString(this, xmlDeclaration)
fun Node.toXmlString(xmlDeclaration: Boolean = false): String {
val writer = StringWriter()
writeXmlString(writer, xmlDeclaration)
return writer.toString().sure()
}
/** Converts the node to an XML String and writes it to the given [[Writer]] */
fun Node.writeXmlString(writer: Writer, xmlDeclaration: Boolean): Unit {
val transformer = createTransformer()
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, if (xmlDeclaration) "no" else "yes")
transformer.transform(DOMSource(this), StreamResult(writer))
}
/** Converts the collection of nodes to an XML String */
fun java.lang.Iterable<Node>.toXmlString(xmlDeclaration: Boolean = false): String {
fun nodesToXmlString(nodes: Iterable<Node>, xmlDeclaration: Boolean = false): String {
// TODO this should work...
// return this.map<Node,String>{it.toXmlString()}.join("")
val builder = StringBuilder()
for (n in this) {
for (n in nodes) {
builder.append(n.toXmlString(xmlDeclaration))
}
return builder.toString().sure()
}
/*
fun Document.toXmlString(xmlDeclaration: Boolean = true): String {
return nodeToXmlString(this, xmlDeclaration)
}
*/
/** Converts the node to an XML String */
fun nodeToXmlString(node: Node, xmlDeclaration: Boolean): String {
val transformer = createTransformer()
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, if (xmlDeclaration) "no" else "yes")
val buffer = StringWriter()
transformer.transform(DOMSource(node), StreamResult(buffer))
return buffer.toString().sure()
}
}