diff --git a/libraries/stdlib/src/dom/Dom.kt b/libraries/stdlib/src/dom/Dom.kt index e925b51d5d2..072c529733e 100644 --- a/libraries/stdlib/src/dom/Dom.kt +++ b/libraries/stdlib/src/dom/Dom.kt @@ -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 { } } +/** Returns an [[Iterator]] over the next siblings of this node */ +fun Node.nextSiblings() : Iterator = NextSiblingIterator(this) + +protected class NextSiblingIterator(var node: Node) : AbstractIterator() { + + 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 = PreviousSiblingIterator(this) + +protected class PreviousSiblingIterator(var node: Node) : AbstractIterator() { + + 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 = nextSiblings().filterIs() + +/** Returns an [[Iterator]] of all the previous [[Element]] siblings */ +fun Node.previousElements(): Iterator = previousSiblings().filterIs() + /** 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 { fun NodeList?.toXmlString(xmlDeclaration: Boolean = false): String { return if (this == null) "" else { - this.toList().toXmlString(xmlDeclaration) + nodesToXmlString(this.toList(), xmlDeclaration) } } diff --git a/libraries/stdlib/src/dom/DomJVM.kt b/libraries/stdlib/src/dom/DomJVM.kt index 31f6373e6f3..49a45b579c0 100644 --- a/libraries/stdlib/src/dom/DomJVM.kt +++ b/libraries/stdlib/src/dom/DomJVM.kt @@ -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.toXmlString(xmlDeclaration: Boolean = false): String { +fun nodesToXmlString(nodes: Iterable, xmlDeclaration: Boolean = false): String { // TODO this should work... // return this.map{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() - -} - +} \ No newline at end of file diff --git a/libraries/stdlib/test/dom/DomBuilderTest.kt b/libraries/stdlib/test/dom/DomBuilderTest.kt index 7720bae7a96..af5bcb49d77 100644 --- a/libraries/stdlib/test/dom/DomBuilderTest.kt +++ b/libraries/stdlib/test/dom/DomBuilderTest.kt @@ -116,7 +116,7 @@ class DomBuilderTest() : TestCase() { fail("Not an Element $grandChild") } val children = doc.rootElement.children() - val xml = children.toXmlString() + val xml = nodesToXmlString(children) println("root element has children: ${xml}") assertEquals(1, children.size()) }