This library can be used to build xml documents from Kotlin code. It is based on the HTML builder described in the Kotlin docs
It is designed to be lightweight and fast. There isn't any validation except to escape text to not violate xml standards.
Apache 2.0
To use in Gradle, simply add the Maven Central repository and then add the following dependency.
repositories {
mavenCentral()
}
dependencies {
compile("org.redundent:kotlin-xml-builder:[VERSION]")
}
Similarly in Maven:
<dependencies>
<dependency>
<groupId>org.redundent</groupId>
<artifactId>kotlin-xml-builder</artifactId>
<version>[VERSION]</version>
</dependency>
</dependencies>
val people = xml("people") {
xmlns = "http://example.com/people"
"person" {
attribute("id", 1)
"firstName" {
-"John"
}
"lastName" {
-"Doe"
}
"phone" {
-"555-555-5555"
}
}
}
val asString = people.toString()
produces
<people xmlns="http://example.com/people">
<person id="1">
<firstName>
John
</firstName>
<lastName>
Doe
</lastName>
<phone>
555-555-5555
</phone>
</person>
</people>
class Person(val id: Long, val firstName: String, val lastName: String, val phone: String)
val listOfPeople = listOf(
Person(1, "John", "Doe", "555-555-5555"),
Person(2, "Jane", "Doe", "555-555-6666")
)
val people = xml("people") {
xmlns = "http://example.com/people"
for (person in listOfPeople) {
"person" {
attribute("id", person.id)
"firstName" {
-person.firstName
}
"lastName" {
-person.lastName
}
"phone" {
-person.phone
}
}
}
}
val asString = people.toString()
produces
<people xmlns="http://example.com/people">
<person id="1">
<firstName>
John
</firstName>
<lastName
>Doe
</lastName>
<phone>
555-555-5555
</phone>
</person>
<person id="2">
<firstName>
Jane
</firstName>
<lastName>
Doe
</lastName>
<phone>
555-555-6666
</phone>
</person>
</people>
Version 1.8.0 added more precise control over how namespaces are used. You can add a namespace to any element or attribute and the correct node/attribute name will be used automatically. When using the new namespace aware methods, you no longer need to manually add the namespace to the element.
See examples of < 1.8.0
and >= 1.8.0
below to produce the following xml
<t:root xmlns:t="https://ns.org">
<t:element t:key="value"/>
</t:root>
xml("t:root") {
namespace("t", "https://ns.org")
"t:element"("t:key" to "value")
}
val ns = Namespace("t", "https://ns.org")
xml("root", ns) {
"element"(ns, Attribute("key", "value", ns))
}
You can also use the Namespace("https://ns.org")
constructor to create a Namespace object that represents the default xmlns.
namespaces
property.You can add processing instructions to any element by using the processingInstruction
method.
xml("root") {
processingInstruction("instruction")
}
<root>
<?instruction?>
</root>
Similarly you can add a global (top-level) instruction by call globalProcessingInstruction
on the
root node. This method only applies to the root. If it is called on any other element, it will be ignored.
xml("root") {
globalProcessingInstruction("xml-stylesheet", "type" to "text/xsl", "href" to "style.xsl")
}
<?xml-stylesheet type="text/xsl" href="https://github.com/redundent/kotlin-xml-builder/blob/main/style.xsl"?>
<root/>
As of version 1.7.4, you can specify a DTD (Document Type Declaration).
xml("root") {
doctype(systemId = "mydtd.dtd")
}
<!DOCTYPE root SYSTEM "mydtd.dtd">
<root/>
Complex DTDs are not supported.
You can now use unsafe text for element and attribute values.
xml("root") {
unsafeText("<xml/>")
}
produces
<root>
<xml/>
</root>
xml("root") {
attribute("attr", unsafe("{"))
}
produces
<root attr="&#123;"/>
You can now control how your xml will look when rendered by passing the new PrintOptions class as an argument to toString
.
pretty
- This is the default and will produce the xml you see above.
singleLineTextElements
- This will render single text element nodes on a single line if pretty
is true
<root>
<element>value</element>
</root>
as opposed to:
<root>
<element>
value
</element>
</root>
useSelfClosingTags
- Use <element/>
instead of <element></element>
for empty tags
useCharacterReference
- Use character references instead of escaped characters. i.e. '
instead of '
You can also read xml documents using the parse
methods. They provide basic
xml parsing and will build a Node
element to build upon.
For more advanced consuming, check out konsume-xml. It includes many more features for consuming documents.
addElement
, addElements
, addElementsBefore
, addElementsAfter
, removeElement
,
removeElements
, and replaceElement
to Node.\
Thanks to @csmile2 for requesting this!addNode
, addNodeBefore
, addNodeAfter
, removeNode
, and replaceNode
in favor of Element methods.unsafe
and unsafeText
methods to allow for unescaped values in elements and attributes.\
Thanks to @krzysztofsroga for requesting this!BREAKING CHANGES
attributes
property on a node will now return an immutable map (Map
instead of LinkedHashMap
). This property can no longer be used to\
manipulate the attributes. Use set
/removeAttribute
for that.private fun parse(Document)
public.\
Thanks to @rkklai for requesting this!useSelfClosingTags
.\
Thanks to @d-wojciechowski for finding this!indent
default is \t
.\
Thanks to @vRallev for adding this!POTENTIAL BREAKING CHANGES
equals
and hashCode
. This could change the behavior of putting nodes in a Set or Map.\
Thanks to @cbartolome for requesting this!BREAKING CHANGES
kotlin-reflect
dependency has been removed from the transitive dependnecies.
This module is only used for controlling element order using @XmlType
.
If your project depends on that feature, you will need to have kotlin-reflect
on the
runtime classpath.\
Thanks to @mvysny for requesting this!processingInstruction
method to do this.\
Thanks to @endofhome for adding this!comment
method to do this.\
Thanks to @ejektaflex for requesting this!BREAKING CHANGES
prettyFormat
should not alter the CDATA content.Charsets
instead of using java.nio.charset.StandardCharsets
. StandardCharsets
is not available in some versions of Android.\
Thanks to @little-fish for submitting and fixing this!BREAKING CHANGES
prettyFormat
to a parameter of toString()
. prettyFormat
in the constructor or util method is no longer available. Fixes issue #7BREAKING CHANGES
org.redundent.kotlin.xml.Node.name
has been renamed to org.redundent.kotlin.xml.Node.nodeName
to avoid clashes with attributes called name
.parse
method.sitemap
method to allow for easy generation of sitemaps (which is what this project was created for in the first place).String.invoke
for elements allowing you to specify elements by just their name (see docs above)filter
, first
, firstOrNull
, and exists
.element("name", "value")
ns
method. Please use namespace(...)
instead.