🎯 Exemples recommandés
Balanced sample collections from various categories for you to explore
Exemples de Sérialisation Android Kotlin
Exemples de sérialisation Android Kotlin incluant la sérialisation JSON, la désérialisation et l'analyse XML
💻 Sérialisation JSON kotlin
🟡 intermediate
⭐⭐⭐
Convertir des objets en chaînes JSON en utilisant Gson et d'autres bibliothèques
⏱️ 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 ===")
}
💻 Désérialisation JSON kotlin
🟡 intermediate
⭐⭐⭐⭐
Analyser les chaînes JSON et les convertir en objets en utilisant 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 ===")
}
💻 Analyse XML kotlin
🟡 intermediate
⭐⭐⭐⭐
Analyser les documents XML en utilisant XmlPullParser et l'analyseur DOM
⏱️ 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 ===")
}