🎯 Ejemplos recomendados
Balanced sample collections from various categories for you to explore
Ejemplos de Serialización Android Kotlin
Ejemplos de serialización Android Kotlin incluyendo serialización JSON, deserialización y análisis XML
💻 Serialización JSON kotlin
🟡 intermediate
⭐⭐⭐
Convertir objetos a cadenas JSON usando Gson y otras bibliotecas
⏱️ 25 min
🏷️ kotlin, android, json, serialization
Prerequisites:
Intermediate Kotlin, Gson library
// Android Kotlin JSON Serialization Examples
// Using Gson library and kotlinx.serialization
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import java.lang.reflect.Type
import java.util.Date
// Data classes for serialization
data class User(
val id: Int,
val username: String,
val email: String,
val age: Int? = null,
val isActive: Boolean = true,
val createdAt: Date? = null
)
data class Product(
val productId: String,
val name: String,
val price: Double,
val tags: List<String>,
val inStock: Boolean
)
data class Order(
val orderId: Int,
val user: User,
val products: List<Product>,
val totalAmount: Double,
val orderDate: String
)
// 1. Basic JSON Serialization with Gson
class BasicJsonSerializer {
private val gson: Gson = Gson()
// Serialize simple object
fun serializeObject(obj: Any): String {
val json = gson.toJson(obj)
println("Serialized: $json")
return json
}
// Serialize with pretty printing
fun serializeObjectPretty(obj: Any): String {
val prettyGson = GsonBuilder()
.setPrettyPrinting()
.create()
val json = prettyGson.toJson(obj)
println("Serialized (pretty):\n$json")
return json
}
// Serialize null values explicitly
fun serializeWithNulls(obj: Any): String {
val gsonWithNulls = GsonBuilder()
.serializeNulls()
.create()
return gsonWithNulls.toJson(obj)
}
// Serialize date in custom format
fun serializeWithDateFormat(obj: Any, dateFormat: String): String {
val gsonWithDateFormat = GsonBuilder()
.setDateFormat(dateFormat)
.create()
return gsonWithDateFormat.toJson(obj)
}
// Serialize with custom field naming
fun serializeWithFieldNaming(obj: Any): String {
val gsonWithLowercase = GsonBuilder()
.setFieldNamingPolicy(
com.google.gson.FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES
)
.create()
return gsonWithLowercase.toJson(obj)
}
}
// 2. Advanced JSON Serialization
class AdvancedJsonSerializer {
// Serialize with exclusion strategy
fun serializeWithExclusion(obj: Any): String {
val gson = GsonBuilder()
.setExclusionStrategies(object : com.google.gson.ExclusionStrategy {
override fun shouldSkipField(field: com.google.gson.FieldAttributes): Boolean {
// Skip fields with specific annotation
return field.getAnnotation(SkipSerialization::class.java) != null
}
override fun shouldSkipClass(clazz: Class<*>): Boolean {
return false
}
})
.create()
return gson.toJson(obj)
}
// Serialize with custom serializer
fun serializeWithCustomSerializer(obj: Any): String {
val gson = GsonBuilder()
.registerTypeAdapter(Date::class.java, DateSerializer())
.create()
return gson.toJson(obj)
}
// Serialize to file
fun serializeToFile(obj: Any, filePath: String): Boolean {
return try {
val gson = Gson()
val json = gson.toJson(obj)
java.io.FileWriter(filePath).use { writer ->
writer.write(json)
}
println("Serialized to file: $filePath")
true
} catch (e: Exception) {
println("Error serializing to file: ${e.message}")
false
}
}
// Serialize with versioning
fun serializeWithVersion(obj: Any, version: Double): String {
val gson = GsonBuilder()
.setVersion(version)
.create()
return gson.toJson(obj)
}
}
// 3. Collection Serialization
class CollectionSerializer {
private val gson: Gson = Gson()
// Serialize list
fun serializeList(list: List<Any>): String {
return gson.toJson(list)
}
// Serialize map
fun serializeMap(map: Map<String, Any>): String {
return gson.toJson(map)
}
// Serialize set
fun serializeSet(set: Set<Any>): String {
return gson.toJson(set)
}
// Serialize nested collections
fun serializeNested(data: Map<String, List<Any>>): String {
return gson.toJson(data)
}
// Serialize array
fun serializeArray(array: Array<Any>): String {
return gson.toJson(array)
}
}
// 4. Streaming JSON Serialization
class StreamingJsonSerializer {
// Serialize using JsonWriter (for large datasets)
fun serializeUsingJsonWriter(data: List<User>, filePath: String): Boolean {
return try {
java.io.FileWriter(filePath).use { writer ->
val jsonWriter = com.google.gson.stream.JsonWriter(writer)
jsonWriter.beginArray()
for (user in data) {
jsonWriter.beginObject()
jsonWriter.name("id").value(user.id.toLong())
jsonWriter.name("username").value(user.username)
jsonWriter.name("email").value(user.email)
user.age?.let { jsonWriter.name("age").value(it.toLong()) }
jsonWriter.name("isActive").value(user.isActive)
jsonWriter.endObject()
}
jsonWriter.endArray()
jsonWriter.close()
}
println("Streamed ${data.size} items to $filePath")
true
} catch (e: Exception) {
println("Error streaming JSON: ${e.message}")
false
}
}
// Serialize with buffering
fun serializeWithBuffer(data: List<Any>, bufferSize: Int): List<String> {
val chunks = mutableListOf<String>()
val gson = Gson()
data.chunked(bufferSize).forEach { chunk ->
chunks.add(gson.toJson(chunk))
}
return chunks
}
}
// 5. Kotlinx Serialization (Alternative)
// Note: Requires kotlinx-serialization plugin
object KotlinxSerializer {
// Example using kotlinx.serialization (if plugin is enabled)
// @Serializable
// data class UserKotlinx(
// val id: Int,
// val username: String,
// val email: String
// )
// fun serializeKotlinx(obj: Any): String {
// return Json.encodeToString(obj)
// }
}
// 6. Custom Date Serializer
class DateSerializer : com.google.gson.JsonSerializer<Date> {
override fun serialize(
src: Date,
typeOfSrc: Type,
context: com.google.gson.JsonSerializationContext
): com.google.gson.JsonElement {
val formatter = java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
return com.google.gson.JsonPrimitive(formatter.format(src))
}
}
// Annotation for skipping fields
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
annotation class SkipSerialization
// Main demonstration
fun demonstrateJsonSerialization() {
println("=== Android Kotlin JSON Serialization Examples ===\n")
// 1. Basic serialization
println("--- 1. Basic Serialization ---")
val basicSerializer = BasicJsonSerializer()
val user = User(
id = 1,
username = "alice",
email = "[email protected]",
age = 25,
isActive = true,
createdAt = Date()
)
val json1 = basicSerializer.serializeObject(user)
println("Simple: $json1")
// 2. Pretty printing
println("\n--- 2. Pretty Printing ---")
val json2 = basicSerializer.serializeObjectPretty(user)
// 3. Serialization with nulls
println("\n--- 3. Serialize with Nulls ---")
val userWithNulls = User(
id = 2,
username = "bob",
email = "[email protected]",
age = null,
isActive = true
)
val json3 = basicSerializer.serializeWithNulls(userWithNulls)
println("With nulls: $json3")
// 4. Date formatting
println("\n--- 4. Date Formatting ---")
val json4 = basicSerializer.serializeWithDateFormat(
user,
"yyyy-MM-dd HH:mm:ss"
)
println("Custom date format: $json4")
// 5. Complex object
println("\n--- 5. Complex Object Serialization ---")
val order = Order(
orderId = 1001,
user = user,
products = listOf(
Product("P001", "Laptop", 999.99, listOf("Electronics", "Computers"), true),
Product("P002", "Mouse", 29.99, listOf("Electronics", "Accessories"), true)
),
totalAmount = 1029.98,
orderDate = "2025-12-27"
)
val json5 = basicSerializer.serializeObjectPretty(order)
println("Order:\n$json5")
// 6. Collections
println("\n--- 6. Collection Serialization ---")
val collectionSerializer = CollectionSerializer()
val users = listOf(
User(1, "alice", "[email protected]", 25),
User(2, "bob", "[email protected]", 30),
User(3, "charlie", "[email protected]", 28)
)
val usersJson = collectionSerializer.serializeList(users)
println("Users list: $usersJson")
val userMap = mapOf(
"user1" to users[0],
"user2" to users[1],
"user3" to users[2]
)
val mapJson = collectionSerializer.serializeMap(userMap)
println("Users map: $mapJson")
// 7. Field naming policy
println("\n--- 7. Field Naming Policy ---")
val json6 = basicSerializer.serializeWithFieldNaming(user)
println("Lowercase with underscores: $json6")
// 8. Versioning
println("\n--- 8. Versioning ---")
val advancedSerializer = AdvancedJsonSerializer()
val json7 = advancedSerializer.serializeWithVersion(user, 1.0)
println("Version 1.0: $json7")
println("\n=== All JSON Serialization Examples Completed ===")
}
💻 Deserialización JSON kotlin
🟡 intermediate
⭐⭐⭐⭐
Analizar cadenas JSON y convertirlas en objetos usando Gson
⏱️ 30 min
🏷️ kotlin, android, json, parsing
Prerequisites:
Intermediate Kotlin, Gson library
// Android Kotlin JSON Deserialization Examples
// Using Gson library for parsing JSON
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import com.google.gson.JsonSyntaxException
import java.lang.reflect.Type
// Data classes for deserialization
data class User(
val id: Int,
val username: String,
val email: String,
val age: Int? = null,
val isActive: Boolean = true,
val createdAt: String? = null
)
data class Product(
val productId: String,
val name: String,
val price: Double,
val tags: List<String>,
val inStock: Boolean
)
data class ApiResponse<T>(
val success: Boolean,
val data: T?,
val message: String?,
val errorCode: Int?
)
// 1. Basic JSON Deserialization
class BasicJsonDeserializer {
private val gson: Gson = Gson()
// Deserialize to simple object
fun <T> deserializeObject(json: String, classOfT: Class<T>): T? {
return try {
val obj = gson.fromJson(json, classOfT)
println("Deserialized: $obj")
obj
} catch (e: JsonSyntaxException) {
println("Error deserializing: ${e.message}")
null
}
}
// Deserialize with pretty JSON handling
fun <T> deserializePretty(json: String, classOfT: Class<T>): T? {
return try {
gson.fromJson(json, classOfT)
} catch (e: Exception) {
println("Error: ${e.message}")
null
}
}
// Deserialize with default values
fun deserializeWithDefaults(json: String): User? {
return try {
gson.fromJson(json, User::class.java)
} catch (e: Exception) {
println("Error: ${e.message}")
null
}
}
}
// 2. Collection Deserialization
class CollectionDeserializer {
private val gson: Gson = Gson()
// Deserialize JSON array to list
fun <T> deserializeList(json: String, classOfT: Class<T>): List<T> {
val listType = TypeToken.getParameterized(List::class.java, classOfT).type
return try {
gson.fromJson(json, listType) ?: emptyList()
} catch (e: Exception) {
println("Error deserializing list: ${e.message}")
emptyList()
}
}
// Deserialize JSON object to map
fun deserializeMap(json: String): Map<String, Any> {
val mapType = object : TypeToken<Map<String, Any>>() {}.type
return try {
gson.fromJson(json, mapType) ?: emptyMap()
} catch (e: Exception) {
println("Error deserializing map: ${e.message}")
emptyMap()
}
}
// Deserialize to set
fun <T> deserializeSet(json: String, classOfT: Class<T>): Set<T> {
val setType = TypeToken.getParameterized(Set::class.java, classOfT).type
return try {
gson.fromJson(json, setType) ?: emptySet()
} catch (e: Exception) {
println("Error deserializing set: ${e.message}")
emptySet()
}
}
// Deserialize nested collections
fun deserializeNestedList(json: String): List<List<String>> {
val nestedType = object : TypeToken<List<List<String>>>() {}.type
return try {
gson.fromJson(json, nestedType) ?: emptyList()
} catch (e: Exception) {
println("Error deserializing nested list: ${e.message}")
emptyList()
}
}
}
// 3. Advanced Deserialization
class AdvancedJsonDeserializer {
private val gson: Gson = Gson()
// Deserialize from file
fun <T> deserializeFromFile(filePath: String, classOfT: Class<T>): T? {
return try {
val file = java.io.File(filePath)
val json = file.readText()
gson.fromJson(json, classOfT)
} catch (e: Exception) {
println("Error reading from file: ${e.message}")
null
}
}
// Deserialize with custom date format
fun deserializeWithDateFormat(json: String, dateFormat: String): User? {
val gsonWithDateFormat = GsonBuilder()
.setDateFormat(dateFormat)
.create()
return try {
gsonWithDateFormat.fromJson(json, User::class.java)
} catch (e: Exception) {
println("Error with custom date format: ${e.message}")
null
}
}
// Deserialize with lenient mode
fun deserializeLenient(json: String): User? {
val lenientGson = GsonBuilder()
.setLenient()
.create()
return try {
lenientGson.fromJson(json, User::class.java)
} catch (e: Exception) {
println("Error in lenient mode: ${e.message}")
null
}
}
// Deserialize generic type
fun <T> deserializeGeneric(json: String, type: Type): T? {
return try {
gson.fromJson(json, type)
} catch (e: Exception) {
println("Error deserializing generic: ${e.message}")
null
}
}
// Deserialize ApiResponse wrapper
fun <T> deserializeApiResponse(json: String, dataType: Type): ApiResponse<T>? {
val apiResponseType = TypeToken.getParameterized(
ApiResponse::class.java,
dataType
).type
return try {
gson.fromJson(json, apiResponseType)
} catch (e: Exception) {
println("Error deserializing API response: ${e.message}")
null
}
}
}
// 4. Safe Deserialization with Validation
class SafeJsonDeserializer {
private val gson: Gson = Gson()
// Deserialize with validation
fun <T> deserializeWithValidation(
json: String,
classOfT: Class<T>,
validator: (T) -> Boolean
): T? {
return try {
val obj = gson.fromJson(json, classOfT)
if (validator(obj)) {
obj
} else {
println("Validation failed")
null
}
} catch (e: Exception) {
println("Error: ${e.message}")
null
}
}
// Deserialize with fallback
fun <T> deserializeWithFallback(
json: String,
classOfT: Class<T>,
fallback: T
): T {
return try {
gson.fromJson(json, classOfT) ?: fallback
} catch (e: Exception) {
println("Error, using fallback: ${e.message}")
fallback
}
}
// Deserialize nullable fields
fun deserializeNullable(json: String): User? {
return try {
gson.fromJson(json, User::class.java)
} catch (e: Exception) {
println("Error with nullable: ${e.message}")
null
}
}
}
// 5. Streaming JSON Deserialization
class StreamingJsonDeserializer {
// Parse large JSON files using JsonReader
fun parseLargeJson(filePath: String): List<User> {
val users = mutableListOf<User>()
try {
java.io.FileReader(filePath).use { reader ->
val jsonReader = com.google.gson.stream.JsonReader(reader)
jsonReader.beginArray()
while (jsonReader.hasNext()) {
jsonReader.beginObject()
var id = 0
var username = ""
var email = ""
var age: Int? = null
var isActive = true
while (jsonReader.hasNext()) {
when (jsonReader.nextName()) {
"id" -> id = jsonReader.nextInt()
"username" -> username = jsonReader.nextString()
"email" -> email = jsonReader.nextString()
"age" -> age = jsonReader.nextInt()
"isActive" -> isActive = jsonReader.nextBoolean()
}
}
jsonReader.endObject()
users.add(User(id, username, email, age, isActive))
}
jsonReader.endArray()
jsonReader.close()
}
} catch (e: Exception) {
println("Error streaming JSON: ${e.message}")
}
return users
}
// Parse specific fields only
fun parseSpecificFields(json: String, fields: Set<String>): Map<String, String> {
val result = mutableMapOf<String, String>()
try {
java.io.StringReader(json).use { reader ->
val jsonReader = com.google.gson.stream.JsonReader(reader)
jsonReader.beginObject()
while (jsonReader.hasNext()) {
val name = jsonReader.nextName()
if (name in fields) {
result[name] = jsonReader.nextString()
} else {
jsonReader.skipValue()
}
}
jsonReader.endObject()
jsonReader.close()
}
} catch (e: Exception) {
println("Error parsing fields: ${e.message}")
}
return result
}
}
// 6. JSON Path Query (Simple)
class JsonPathQuery {
private val gson: Gson = Gson()
// Get nested value
fun getNestedValue(json: String, path: String): String? {
return try {
val jsonObj = gson.fromJson(json, com.google.gson.JsonObject::class.java)
val parts = path.split(".")
var current: com.google.gson.JsonElement = jsonObj
for (part in parts) {
if (current.isJsonObject) {
current = current.asJsonObject.get(part)
}
}
current.asString
} catch (e: Exception) {
println("Error getting nested value: ${e.message}")
null
}
}
// Check if field exists
fun hasField(json: String, fieldName: String): Boolean {
return try {
val jsonObj = gson.fromJson(json, com.google.gson.JsonObject::class.java)
jsonObj.has(fieldName)
} catch (e: Exception) {
false
}
}
// Extract all values of a field from array
fun extractFieldFromArray(json: String, fieldName: String): List<String> {
val values = mutableListOf<String>()
try {
val jsonArray = gson.fromJson(json, com.google.gson.JsonArray::class.java)
for (element in jsonArray) {
val obj = element.asJsonObject
if (obj.has(fieldName)) {
values.add(obj.get(fieldName).asString)
}
}
} catch (e: Exception) {
println("Error extracting field: ${e.message}")
}
return values
}
}
// Main demonstration
fun demonstrateJsonDeserialization() {
println("=== Android Kotlin JSON Deserialization Examples ===\n")
// 1. Basic deserialization
println("--- 1. Basic Deserialization ---")
val basicDeserializer = BasicJsonDeserializer()
val userJson = """{"id":1,"username":"alice","email":"[email protected]","age":25,"isActive":true}"""
val user = basicDeserializer.deserializeObject(userJson, User::class.java)
println("Deserialized user: $user")
// 2. Pretty JSON
println("\n--- 2. Pretty JSON ---")
val prettyJson = """
{
"id": 2,
"username": "bob",
"email": "[email protected]",
"age": 30,
"isActive": true
}
""".trimIndent()
val user2 = basicDeserializer.deserializePretty(prettyJson, User::class.java)
println("Deserialized from pretty: $user2")
// 3. Collection deserialization
println("\n--- 3. Collection Deserialization ---")
val collectionDeserializer = CollectionDeserializer()
val usersJson = """[
{"id":1,"username":"alice","email":"[email protected]"},
{"id":2,"username":"bob","email":"[email protected]"},
{"id":3,"username":"charlie","email":"[email protected]"}
]"""
val users = collectionDeserializer.deserializeList(usersJson, User::class.java)
println("Deserialized ${users.size} users:")
users.forEach { println(" - ${it.username}") }
// 4. Map deserialization
val mapJson = """{"name":"Product","price":29.99,"inStock":true}"""
val map = collectionDeserializer.deserializeMap(mapJson)
println("\nDeserialized map: $map")
// 5. Generic deserialization
println("\n--- 5. Generic Type Deserialization ---")
val advancedDeserializer = AdvancedJsonDeserializer()
val apiResponseJson = """
{
"success": true,
"data": {"id":1,"username":"alice","email":"[email protected]"},
"message": "User found",
"errorCode": null
}
""".trimIndent()
val userType = object : TypeToken<User>() {}.type
val response = advancedDeserializer.deserializeApiResponse<User>(apiResponseJson, userType)
println("API Response: success=${response?.success}, data=${response?.data}")
// 6. Safe deserialization
println("\n--- 6. Safe Deserialization ---")
val safeDeserializer = SafeJsonDeserializer()
val validatedUser = safeDeserializer.deserializeWithValidation(
userJson,
User::class.java
) { user -> user.email.contains("@") }
println("Validated user: $validatedUser")
val fallbackUser = safeDeserializer.deserializeWithFallback(
"{invalid json}",
User::class.java,
User(0, "fallback", "[email protected]")
)
println("Fallback user: $fallbackUser")
// 7. JSON path
println("\n--- 7. JSON Path Query ---")
val pathQuery = JsonPathQuery()
val complexJson = """
{
"user": {
"id": 1,
"profile": {
"username": "alice",
"email": "[email protected]"
}
}
}
""".trimIndent()
val email = pathQuery.getNestedValue(complexJson, "user.profile.email")
println("Extracted email: $email")
val hasField = pathQuery.hasField(complexJson, "user")
println("Has 'user' field: $hasField")
println("\n=== All JSON Deserialization Examples Completed ===")
}
💻 Análisis XML kotlin
🟡 intermediate
⭐⭐⭐⭐
Analizar documentos XML usando XmlPullParser y DOM parser
⏱️ 30 min
🏷️ kotlin, android, xml, parsing
Prerequisites:
Intermediate Kotlin, XML basics
// Android Kotlin XML Parsing Examples
// Using XmlPullParser and DOM parser
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserFactory
import org.w3c.dom.Document
import org.w3c.dom.Element
import org.w3c.dom.Node
import org.w3c.dom.NodeList
import javax.xml.parsers.DocumentBuilderFactory
import java.io.StringReader
// Data classes for XML
data class Book(
val id: Int,
val title: String,
val author: String,
val price: Double,
val genre: String?
)
data class User(
val id: Int,
val username: String,
val email: String,
val address: Address?
)
data class Address(
val street: String,
val city: String,
val country: String
)
// 1. Basic XML Parsing with XmlPullParser
class BasicXmlParser {
// Parse simple XML document
fun parseSimpleXml(xml: String): List<Book> {
val books = mutableListOf<Book>()
val factory = XmlPullParserFactory.newInstance()
val parser = factory.newPullParser()
parser.setInput(StringReader(xml))
var eventType = parser.eventType
var currentId = 0
var currentTitle = ""
var currentAuthor = ""
var currentPrice = 0.0
var currentGenre: String? = null
while (eventType != XmlPullParser.END_DOCUMENT) {
when (eventType) {
XmlPullParser.START_TAG -> {
when (parser.name) {
"book" -> {
currentId = parser.getAttributeValue(null, "id").toInt()
}
"title" -> {
currentTitle = parser.nextText()
}
"author" -> {
currentAuthor = parser.nextText()
}
"price" -> {
currentPrice = parser.nextText().toDouble()
}
"genre" -> {
currentGenre = parser.nextText()
}
}
}
XmlPullParser.END_TAG -> {
if (parser.name == "book") {
books.add(Book(currentId, currentTitle, currentAuthor, currentPrice, currentGenre))
}
}
}
eventType = parser.next()
}
return books
}
// Parse XML with nested elements
fun parseNestedXml(xml: String): List<User> {
val users = mutableListOf<User>()
val factory = XmlPullParserFactory.newInstance()
val parser = factory.newPullParser()
parser.setInput(StringReader(xml))
var eventType = parser.eventType
var currentId = 0
var currentUsername = ""
var currentEmail = ""
var currentStreet = ""
var currentCity = ""
var currentCountry = ""
var inAddress = false
while (eventType != XmlPullParser.END_DOCUMENT) {
when (eventType) {
XmlPullParser.START_TAG -> {
when (parser.name) {
"user" -> {
currentId = parser.getAttributeValue(null, "id").toInt()
}
"username" -> currentUsername = parser.nextText()
"email" -> currentEmail = parser.nextText()
"address" -> inAddress = true
"street" -> if (inAddress) currentStreet = parser.nextText()
"city" -> if (inAddress) currentCity = parser.nextText()
"country" -> if (inAddress) currentCountry = parser.nextText()
}
}
XmlPullParser.END_TAG -> {
if (parser.name == "user") {
val address = if (currentStreet.isNotEmpty()) {
Address(currentStreet, currentCity, currentCountry)
} else null
users.add(User(currentId, currentUsername, currentEmail, address))
// Reset
currentStreet = ""
currentCity = ""
currentCountry = ""
inAddress = false
}
}
}
eventType = parser.next()
}
return users
}
}
// 2. DOM Parser
class DomXmlParser {
// Parse XML using DOM
fun parseWithDom(xml: String): List<Book> {
val books = mutableListOf<Book>()
try {
val factory = DocumentBuilderFactory.newInstance()
val builder = factory.newDocumentBuilder()
val document = builder.parse(
javax.xml.parsers.InputSource(StringReader(xml))
)
val bookNodes = document.getElementsByTagName("book")
for (i in 0 until bookNodes.length) {
val bookElement = bookNodes.item(i) as Element
val id = bookElement.getAttribute("id").toInt()
val title = getTextContent(bookElement, "title")
val author = getTextContent(bookElement, "author")
val price = getTextContent(bookElement, "price").toDouble()
val genreNode = bookElement.getElementsByTagName("genre").item(0)
val genre = if (genreNode != null) genreNode.textContent else null
books.add(Book(id, title, author, price, genre))
}
} catch (e: Exception) {
println("Error parsing with DOM: ${e.message}")
}
return books
}
// Get text content of child element
private fun getTextContent(parent: Element, tagName: String): String {
val nodes = parent.getElementsByTagName(tagName)
return if (nodes.length > 0) {
nodes.item(0).textContent
} else {
""
}
}
// Parse with attributes
fun parseAttributes(xml: String): Map<String, Map<String, String>> {
val result = mutableMapOf<String, Map<String, String>>()
try {
val factory = DocumentBuilderFactory.newInstance()
val builder = factory.newDocumentBuilder()
val document = builder.parse(
javax.xml.parsers.InputSource(StringReader(xml))
)
val elements = document.documentElement.childNodes
for (i in 0 until elements.length) {
val node = elements.item(i)
if (node.nodeType == Node.ELEMENT_NODE) {
val element = node as Element
val attrs = mutableMapOf<String, String>()
for (j in 0 until element.attributes.length) {
val attr = element.attributes.item(j)
attrs[attr.nodeName] = attr.nodeValue
}
result[element.tagName] = attrs
}
}
} catch (e: Exception) {
println("Error parsing attributes: ${e.message}")
}
return result
}
}
// 3. XML to Object Mapper
class XmlObjectMapper {
// Parse XML to generic map
fun xmlToMap(xml: String): Map<String, Any> {
val result = mutableMapOf<String, Any>()
val factory = XmlPullParserFactory.newInstance()
val parser = factory.newPullParser()
parser.setInput(StringReader(xml))
var eventType = parser.eventType
var currentKey = ""
val stack = mutableListOf<String>()
while (eventType != XmlPullParser.END_DOCUMENT) {
when (eventType) {
XmlPullParser.START_TAG -> {
currentKey = parser.name
stack.add(currentKey)
}
XmlPullParser.TEXT -> {
val text = parser.text.trim()
if (text.isNotEmpty() && stack.size > 0) {
result[stack.joinToString(".")] = text
}
}
XmlPullParser.END_TAG -> {
if (stack.isNotEmpty()) {
stack.removeAt(stack.size - 1)
}
}
}
eventType = parser.next()
}
return result
}
// Extract specific elements
fun extractElements(xml: String, elementName: String): List<String> {
val elements = mutableListOf<String>()
val factory = XmlPullParserFactory.newInstance()
val parser = factory.newPullParser()
parser.setInput(StringReader(xml))
var eventType = parser.eventType
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG && parser.name == elementName) {
elements.add(parser.nextText())
}
eventType = parser.next()
}
return elements
}
// Extract attributes
fun extractAttributes(xml: String, elementName: String): List<Map<String, String>> {
val attributesList = mutableListOf<Map<String, String>>()
val factory = XmlPullParserFactory.newInstance()
val parser = factory.newPullParser()
parser.setInput(StringReader(xml))
var eventType = parser.eventType
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG && parser.name == elementName) {
val attrs = mutableMapOf<String, String>()
for (i in 0 until parser.attributeCount) {
attrs[parser.getAttributeName(i)] = parser.getAttributeValue(i)
}
attributesList.add(attrs)
}
eventType = parser.next()
}
return attributesList
}
}
// 4. XML Validation and Utilities
class XmlUtilities {
// Validate XML format
fun isValidXml(xml: String): Boolean {
return try {
val factory = XmlPullParserFactory.newInstance()
val parser = factory.newPullParser()
parser.setInput(StringReader(xml))
var eventType = parser.eventType
while (eventType != XmlPullParser.END_DOCUMENT) {
eventType = parser.next()
}
true
} catch (e: Exception) {
println("Invalid XML: ${e.message}")
false
}
}
// Format XML (pretty print)
fun formatXml(xml: String): String {
try {
val factory = DocumentBuilderFactory.newInstance()
val builder = factory.newDocumentBuilder()
val document = builder.parse(
javax.xml.parsers.InputSource(StringReader(xml))
)
// Use transformer for pretty printing
val transformer = javax.xml.transform.TransformerFactory.newInstance().newTransformer()
transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "yes")
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2")
val writer = java.io.StringWriter()
transformer.transform(
javax.xml.transform.dom.DOMSource(document),
javax.xml.transform.stream.StreamResult(writer)
)
return writer.toString()
} catch (e: Exception) {
println("Error formatting XML: ${e.message}")
return xml
}
}
// Count elements
fun countElements(xml: String, elementName: String): Int {
val factory = XmlPullParserFactory.newInstance()
val parser = factory.newPullParser()
parser.setInput(StringReader(xml))
var count = 0
var eventType = parser.eventType
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG && parser.name == elementName) {
count++
}
eventType = parser.next()
}
return count
}
}
// Main demonstration
fun demonstrateXmlParsing() {
println("=== Android Kotlin XML Parsing Examples ===\n")
// 1. Basic XML parsing
println("--- 1. Basic XML Parsing ---")
val basicParser = BasicXmlParser()
val booksXml = """
<catalog>
<book id="1">
<title>The Great Gatsby</title>
<author>F. Scott Fitzgerald</author>
<price>12.99</price>
<genre>Fiction</genre>
</book>
<book id="2">
<title>To Kill a Mockingbird</title>
<author>Harper Lee</author>
<price>14.99</price>
<genre>Southern Gothic</genre>
</book>
<book id="3">
<title>1984</title>
<author>George Orwell</author>
<price>11.99</price>
</book>
</catalog>
""".trimIndent()
val books = basicParser.parseSimpleXml(booksXml)
println("Parsed ${books.size} books:")
books.forEach { book ->
println(" - ${book.title} by ${book.author} ($${book.price})")
}
// 2. Nested XML parsing
println("\n--- 2. Nested XML Parsing ---")
val usersXml = """
<users>
<user id="1">
<username>alice</username>
<email>[email protected]</email>
<address>
<street>123 Main St</street>
<city>NYC</city>
<country>USA</country>
</address>
</user>
<user id="2">
<username>bob</username>
<email>[email protected]</email>
</user>
</users>
""".trimIndent()
val users = basicParser.parseNestedXml(usersXml)
println("Parsed ${users.size} users:")
users.forEach { user ->
println(" - ${user.username} (${user.email})")
user.address?.let {
println(" Address: ${it.street}, ${it.city}")
}
}
// 3. DOM parsing
println("\n--- 3. DOM Parsing ---")
val domParser = DomXmlParser()
val booksFromDom = domParser.parseWithDom(booksXml)
println("Parsed via DOM: ${booksFromDom.size} books")
// 4. XML to map
println("\n--- 4. XML to Map ---")
val mapper = XmlObjectMapper()
val simpleXml = """
<config>
<app_name>MyApp</app_name>
<version>1.0.0</version>
<debug>true</debug>
</config>
""".trimIndent()
val configMap = mapper.xmlToMap(simpleXml)
println("Config map:")
configMap.forEach { (key, value) ->
println(" $key: $value")
}
// 5. Extract elements
println("\n--- 5. Extract Elements ---")
val titles = mapper.extractElements(booksXml, "title")
println("Book titles: $titles")
// 6. Extract attributes
val bookAttrs = mapper.extractAttributes(booksXml, "book")
println("\nBook attributes:")
bookAttrs.forEach { attrs ->
println(" Book ${attrs["id"]}")
}
// 7. Validation
println("\n--- 6. Validation ---")
val utilities = XmlUtilities()
val isValid = utilities.isValidXml(booksXml)
println("Is valid XML: $isValid")
val elementCount = utilities.countElements(booksXml, "book")
println("Book count: $elementCount")
// 8. Format XML
println("\n--- 7. Format XML ---")
val unformattedXml = "<catalog><book id="1"><title>Test</title></book></catalog>"
val formattedXml = utilities.formatXml(unformattedXml)
println("Formatted XML:\n$formattedXml")
println("\n=== All XML Parsing Examples Completed ===")
}