All Downloads are FREE. Search and download functionalities are using the official Maven repository.

main.net.joeaustin.easyxml.XmlElement.kt Maven / Gradle / Ivy

The newest version!
package net.joeaustin.easyxml

private const val PADDING = "    "

class XmlElement(
    val name: String,
    val innerText: String,
    val attributes: List,
    val subComponents: List
) : BaseXmlComponent() {

    operator fun get(childName: String): List {
        return getChildren(childName)
    }

    fun getChildren(name: String, ignoreCase: Boolean = false): List {
        return subComponents
            .filter { child ->
                child is XmlElement && child.name.equals(name, ignoreCase)
            }
            .mapNotNull { child -> child as? XmlElement }
    }

    fun getChildren(): List {
        return subComponents
            .mapNotNull { component -> component as? XmlElement }
    }

    fun getFirstChild(name: String, ignoreCase: Boolean = false): XmlElement? {
        return subComponents
            .firstOrNull { c -> (c as? XmlElement)?.name.equals(name, ignoreCase) } as? XmlElement
    }

    fun getAttributeValue(name: String, ignoreCase: Boolean = false): String? {
        return attributes.firstOrNull { attr ->
            attr.name.equals(name, ignoreCase)
        }?.value
    }

    override fun build(sb: StringBuilder, currentPadding: String, buildOptions: XmlBuildOptions) {
        val normalizedName = normalizeKey(name)
        sb.append(currentPadding)
        sb.append("<")
        sb.append(normalizedName)

        attributes.forEach { attr ->
            attr.build(sb, "", buildOptions)
        }

        if (innerText.isNotEmpty()) {
            sb.append(">")
            sb.append(escapeText(innerText))
        } else if (subComponents.isNotEmpty()) {
            if (buildOptions.pretty) {
                sb.appendln(">")
            } else {
                sb.append(">")
            }

            val subPadding = if (buildOptions.pretty) currentPadding + PADDING else ""

            subComponents.forEach { child ->
                child.build(sb, subPadding, buildOptions)
            }
        }

        if (innerText.isEmpty() && subComponents.isEmpty()) {
            if (buildOptions.pretty) {
                sb.appendln("/>")
            } else {
                sb.append("/>")
            }
        } else {
            //If we're doing pretty print and there aren't children, the closing tag should be
            //on a new line indented to match the start tag
            if (buildOptions.pretty && subComponents.isNotEmpty()) {
                sb.append(currentPadding)
            }
            sb.append("")
            } else {
                sb.append(">")
            }
        }

    }

    override fun toString(): String {
        val sb = java.lang.StringBuilder()
        build(sb, "", XmlBuildOptions())
        return sb.toString()
    }

    class Builder(val name: String) {
        private val attributes = ArrayList()
        private val children = ArrayList()
        private var innerText = ""

        fun addInnerText(text: String) {
            innerText = text
        }

        fun addAttribute(attr: XmlAttribute) {
            attributes.add(attr)
        }

        fun addXmlElement(element: XmlElement) {
            children.add(element)
        }

        fun addComment(comment: XmlComment) {
            children.add(comment)
        }

        fun addComment(commentText: String) {
            addComment(XmlComment(commentText))
        }

        fun build(): XmlElement {
            return XmlElement(name, innerText, attributes, children)
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy