How would one parse XML in Kotlin with encoding utf8? - android

I am new to Kotlin, trying to build my first Android App.
I have an xml string that I would like to parse to a class. The xml comes from a soap webservice call and the result is in a string called xmlOut.pcReturnData which looks like this:
<?xml version="1.0" ?><ShipmentDetail><Waybill><WaybillNumber>0087073606</WaybillNumber><ServiceType>ECONOMY ROAD</ServiceType><CurrentStatus>Proof of delivery</CurrentStatus><CurrentStatusCode>POD</CurrentStatusCode><DeliveredDate>18052017</DeliveredDate><DeliveredTime>1200</DeliveredTime><ReceiverName>PIET</ReceiverName><NumberOfPieces>3</NumberOfPieces><TotalWeight> 330.00</TotalWeight><Contents/><ManifestReference/><OriginSuburb>MILNERTON</OriginSuburb><OriginHub>ATL</OriginHub><DestinationSuburb>BLOEMFONTEIN</DestinationSuburb><DestinationHub>BFN</DestinationHub><ShipperReference>0087073606</ShipperReference><TrackingEvents><BranchCode>ATL</BranchCode><EventDate>15052017</EventDate><EventTime>1158</EventTime><EventDescription>Waybill Created</EventDescription><EventCode>WBLCRE</EventCode></TrackingEvents><TrackingEvents><BranchCode>ATL</BranchCode><EventDate>15052017</EventDate><EventTime>1224</EventTime><EventDescription>In Trip</EventDescription><EventCode>WBLALL</EventCode></TrackingEvents><TrackingEvents><BranchCode>CPT</BranchCode><EventDate>15052017</EventDate><EventTime>1530</EventTime><EventDescription>On Floor</EventDescription><EventCode>WBLDAL</EventCode></TrackingEvents><TrackingEvents><BranchCode>CPT</BranchCode><EventDate>15052017</EventDate><EventTime>2238</EventTime><EventDescription>In Trip</EventDescription><EventCode>WBLALL</EventCode></TrackingEvents><TrackingEvents><BranchCode>BFN</BranchCode><EventDate>16052017</EventDate><EventTime>1534</EventTime><EventDescription>On Floor</EventDescription><EventCode>WBLDAL</EventCode></TrackingEvents><TrackingEvents><BranchCode>BFN</BranchCode><EventDate>16052017</EventDate><EventTime>1858</EventTime><EventDescription>In Trip</EventDescription><EventCode>WBLALD</EventCode></TrackingEvents><TrackingEvents><BranchCode>BFN</BranchCode><EventDate>17052017</EventDate><EventTime>1722</EventTime><EventDescription>Comments captured</EventDescription><EventCode>WBLCOM</EventCode></TrackingEvents><TrackingEvents><BranchCode>BFN</BranchCode><EventDate>17052017</EventDate><EventTime>1726</EventTime><EventDescription>In Trip</EventDescription><EventCode>WBLALD</EventCode></TrackingEvents><TrackingEvents><BranchCode>BFN</BranchCode><EventDate>18052017</EventDate><EventTime>1835</EventTime><EventDescription>Waybill Delivered</EventDescription><EventCode>WBLDLV</EventCode></TrackingEvents><TrackingEvents><BranchCode>CHLR</BranchCode><EventDate>19052017</EventDate><EventTime>1047</EventTime><EventDescription>POD</EventDescription><EventCode>PODCRE</EventCode></TrackingEvents></Waybill></ShipmentDetail>
The class i created:
data class ShipmentDetail(val Waybill: Waybill?)
data class TrackingEventsList(val EventDate: Number?, val EventTime: Number?, val EventDescription: String?, val BranchCode: String?, val EventCode: String?)
data class Waybill(val TrackingEvents: List<TrackingEventsList>?, val WaybillNumber: String?, val CurrentStatus: String?, val ShipperReference: String?, val CurrentStatusCode: String?, val ManifestReference: String?, val NumberOfPieces: Number?, val DeliveredDate: Number?, val OriginSuburb: String?, val TotalWeight: Number?, val Contents: String?, val DestinationSuburb: String?, val ServiceType: String?, val DestinationHub: String?, val DeliveredTime: Number?, val ReceiverName: String?, val OriginHub: String?)
I would like to parse from the xml to the class ShipmentDetail, is there a build in XMLParser in Kotlin or would I need to use some kind of plugin or extension?

Related

Can't parse json correctly

need help in parsing this json file from this endpoint
http://ergast.com/api/f1/constructors
this is my data class
data class Teams(
val MRData: MRdata
){
data class MRdata(
val ConstructorTable: ConstructorsTable,
val limit: String,
val offset: String,
val series: String,
val total: String,
val url: String,
val xmlns: String
){
data class ConstructorsTable(
val Constructors: List<Constructor>?
) {
data class Constructor(
val constructorId: String?,
val name: String?,
val nationality: String?,
val url: String?
)
}
}
}
when i use Teams class as a return model it logs actual data but, when i try to return specific data like constructorID or nationality it returns null.

How to parse json in android

https://api.mojilala.com/v1/stickers/trending?api_key=dc6zaTOxFJmzC
data class RootApi(val data : List<AllData>)
data class AllData(val images : ImageSticker)
data class ImageSticker(val fixed_height : ActualImage)
data class ActualImage(val url : String)
is this the correct POJO class or not according to given api
Firstly, hide your API key in the question. Coming to generating data classes of JSON. I would suggest you use the following Plugin
https://plugins.jetbrains.com/plugin/9960-json-to-kotlin-class-jsontokotlinclass-
And no that is not the correct data class. Infact it is very big. I can't even paste it all in the answer. Use the plugin. Paste the JSON response and generate yourself.
Following the answer from #che10 you should end up with the below:
data class Data(
// Assuming you are using Moshi https://github.com/square/moshi
// Use #SerializedName("data") if you're using Gson
#Json(name="data")
val stickers: List<Sticker>,
val meta: Meta,
val pagination: Pagination
)
data class Sticker(
val designer: String,
val id: String,
val images: Images,
val is_animated: Boolean,
val rating: String,
val tags: List<String>,
val url: String
)
data class Pagination(
val offset: String,
val total: Int,
val total_count: Int
)
data class Meta(
val msg: String,
val status: Int
)
// Different fields but of two types so we can reuse the classes
// Difference between AnimatedImage and StillImage is the two webp fields
data class Images(
// Animated images
val fixed_height: AnimatedImage,
val fixed_height_downsampled: AnimatedImage,
val fixed_height_medium: AnimatedImage,
val fixed_height_medium_downsampled: AnimatedImage,
val fixed_height_small: AnimatedImage,
val fixed_width: AnimatedImage,
val fixed_width_downsampled: AnimatedImage,
val fixed_width_medium: AnimatedImage,
val fixed_width_medium_downsampled: AnimatedImage,
val fixed_width_small: AnimatedImage,
// Still images
val fixed_height_still: StillImage,
val fixed_height_medium_still: StillImage,
val fixed_height_small_still: StillImage,
val fixed_width_still: StillImage,
val fixed_width_medium_still: StillImage,
val fixed_width_small_still: StillImage,
)
data class StillImage(
val url: String,
val size: Int,
val height: Int,
val width: Int,
)
data class AnimatedImage(
val url: String,
val size: Int,
val height: Int,
val width: Int,
val webp: String,
val webp_size: Int
)

Store Json (Retrofit response) in to Room Database

I'm new to Room database, I have JSON response from MSGraph API, which is List of Calendar events.
I want to store this response in Room database .
Sample response from the retrofit
data
{
"#odata.context":"",
"value":[
{
"#odata.etag":"W/\"arcvR4W/==\"",
"id":"AAvR4W-QUGEzDhwKmVNegAAFPBq3AAAEA==",
"createdDateTime":"2020-05-28T11:15:19.3397025Z",
"lastModifiedDateTime":"2020-09-08T15:57:16.2356808Z",
"changeKey":"arcvR4W/==",
"categories":[
],
"transactionId":null,
"originalStartTimeZone":"UTC",
"originalEndTimeZone":"UTC",
"iCalUId":"040000008200E00074C5B7101A82E831",
"reminderMinutesBeforeStart":15,
"isReminderOn":true,
"hasAttachments":false,
"subject":"Canceled: discussion",
"bodyPreview":"time didnt set correctly, so cancelling the call",
"importance":"high",
"sensitivity":"normal",
"isAllDay":true,
"isCancelled":true,
"isOrganizer":false,
"responseRequested":true,
"seriesMasterId":"AAMkADU3MAAAAENAABqty9Hhb9BQYTMOHAqZU16AAAU8GrcAAA=",
"showAs":"free",
"type":"occurrence",
"webLink":"https://outlook.office365.com/",
"onlineMeetingUrl":null,
"isOnlineMeeting":true,
"onlineMeetingProvider":"teams",
"allowNewTimeProposals":true,
"isDraft":false,
"hideAttendees":false,
"responseStatus":{
"response":"accepted",
"time":"2020-05-28T11:15:00Z"
},
"body":{
"contentType":"html",
"content":"<html>\r\n<head>\r\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\r\n<meta content=\"text/html; charset=us-ascii\">\r\n</head>\r\n<body>\r\n<div>time didnt set correctly, so cancelling the call</div>\r\n</body>\r\n</html>\r\n"
},
"start":{
"dateTime":"2021-03-11T00:00:00.0000000",
"timeZone":"UTC"
},
"end":{
"dateTime":"2021-03-12T00:00:00.0000000",
"timeZone":"UTC"
},
"location":{
"displayName":"",
"locationType":"default",
"uniqueIdType":"unknown",
"address":{
},
"coordinates":{
}
},
"locations":[
],
"recurrence":null,
"attendees":[
{
"type":"required",
"status":{
"response":"none",
"time":"0001-01-01T00:00:00Z"
},
"emailAddress":{
"name":"abc",
"address":"abc#mail.com"
}
},
{
"type":"required",
"status":{
"response":"none",
"time":"0001-01-01T00:00:00Z"
},
"emailAddress":{
"name":"xyz",
"address":"xyz#mail.com"
}
}
],
"organizer":{
"emailAddress":{
"name":"abc",
"address":"abc#mail.com"
}
},
"onlineMeeting":{
"joinUrl":""
}
},
more elements from list
]
}
I searched the forum but did not get any right solution.
I want to store this response in Room database. Can someone help me the correct approach to follow.
Thanks
you should create "CalendarEvent" object and make response of retrofit be like this Call
after that you need to create entities from your models and create dao (contain methods to insert,get,update and delete the data from db)
and in your repository when you receive the data map it to your db entity
with your mapper (you can use extension to map your own data)
I convert that json to kotlin data classes and you can create db entites inspired from those models
data class Address()
data class Attendees(val type: String?, val status: Status?, val emailAddress: EmailAddress?)
data class CalendarEvent(val id: String?, val createdDateTime: String?, val lastModifiedDateTime: String?, val changeKey: String?, val categories: List<Any>?, val transactionId: Any?, val originalStartTimeZone: String?, val originalEndTimeZone: String?, val iCalUId: String?, val reminderMinutesBeforeStart: Number?, val isReminderOn: Boolean?, val hasAttachments: Boolean?, val subject: String?, val bodyPreview: String?, val importance: String?, val sensitivity: String?, val isAllDay: Boolean?, val isCancelled: Boolean?, val isOrganizer: Boolean?, val responseRequested: Boolean?, val seriesMasterId: String?, val showAs: String?, val type: String?, val webLink: String?, val onlineMeetingUrl: Any?, val isOnlineMeeting: Boolean?, val onlineMeetingProvider: String?, val allowNewTimeProposals: Boolean?, val isDraft: Boolean?, val hideAttendees: Boolean?, val responseStatus: ResponseStatus?, val body: Body?, val start: Start?, val end: End?, val location: Location?, val locations: List<Any>?, val recurrence: Any?, val attendees: List<Attendees>?, val organizer: Organizer?, val onlineMeeting: OnlineMeeting?)
data class Body(val contentType: String?, val content: String?)
data class Coordinates()
data class EmailAddress(val name: String?, val address: String?)
data class End(val dateTime: String?, val timeZone: String?)
data class Location(val displayName: String?, val locationType: String?, val uniqueIdType: String?, val address: Address?, val coordinates: Coordinates?)
data class OnlineMeeting(val joinUrl: String?)
data class Organizer(val emailAddress: EmailAddress?)
data class ResponseStatus(val response: String?, val time: String?)
data class Start(val dateTime: String?, val timeZone: String?)
data class Status(val response: String?, val time: String?)

ERROR: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $

I'm trying to create a POST Request using Retrofit2 and I created the next classes:
My JSON Data: https://jsonblob.com/d7b06b4c-2e4b-11eb-967c-5704a225d894
Model Class
data class StatsModel(
#SerializedName("actionRights")
val actionRights : MutableList<ActionRights>?,
#SerializedName("stats")
val stats : Stats?,
#SerializedName("markers")
val markers : MutableList<Markers>?
) {
data class ActionRights (
#SerializedName("hasArticlePriceChangeRights") val hasArticlePriceChangeRights : Boolean?,
#SerializedName("hasStockLevelViewRights") val hasStockLevelViewRights : Boolean?
)
data class Stats (
#SerializedName("errors") val errors : Int?,
#SerializedName("warnings") val warnings : Int?,
#SerializedName("outOfOrder") val outOfOrder : Int?,
#SerializedName("running") val running : Int?
)
data class Markers (
#SerializedName("deviceGuid") val deviceGuid : String?,
#SerializedName("lat") val lat : Double?,
#SerializedName("lng") val lng : Double?,
#SerializedName("title") val title : Int?,
#SerializedName("city") val city : String?,
#SerializedName("street") val street : Int?,
#SerializedName("serialNumber") val serialNumber : Int?,
#SerializedName("LastStatusMessageDateTime") val lastStatusMessageDateTime : String?,
#SerializedName("LastStatusMessageBitSet_0_63") val lastStatusMessageBitSet_0_63 : Int?,
#SerializedName("LastStatusMessageBitSet_64_127") val lastStatusMessageBitSet_64_127 : Int?,
#SerializedName("ActionsStatus") val actionsStatus : Int?,
#SerializedName("SpareColumn1") val spareColumn1 : String?,
#SerializedName("SpareColumn2") val spareColumn2 : String?,
#SerializedName("SpareColumn3") val spareColumn3 : String?,
#SerializedName("SpareColumn4") val spareColumn4 : String?,
#SerializedName("SpareColumn5") val spareColumn5 : String?,
#SerializedName("SpareColumn6") val spareColumn6 : String?,
#SerializedName("SpareColumn7") val spareColumn7 : String?,
#SerializedName("SpareColumn8") val spareColumn8 : String?,
#SerializedName("SpareColumn9") val spareColumn9 : String?,
#SerializedName("SpareColumn10") val spareColumn10 : String?,
#SerializedName("EstimatedDeliveryDateTime") val estimatedDeliveryDateTime : String?,
#SerializedName("IpAddress") val ipAddress : String?,
#SerializedName("Active") val active : Int?,
#SerializedName("ParentAreaGuid") val parentAreaGuid : String?,
#SerializedName("AreaGuid") val areaGuid : String?,
#SerializedName("TariffGroupGuid") val tariffGroupGuid : String?,
#SerializedName("DeviceType") val deviceType : String?,
#SerializedName("EstimateArticleName") val estimateArticleName : String?,
#SerializedName("EstimateArticleGuid") val estimateArticleGuid : String?,
#SerializedName("lastCoinboxExchange") val lastCoinboxExchange : String?,
#SerializedName("lastStatusUpdateTime") val lastStatusUpdateTime : String?,
#SerializedName("reportDateTime") val reportDateTime : String?,
#SerializedName("hasFinancialInfo") val hasFinancialInfo : Boolean?,
#SerializedName("ticketsSold") val ticketsSold : Int?,
#SerializedName("cash") val cash : Int?,
#SerializedName("cashless") val cashless : Int?,
#SerializedName("hasStockLevel") val hasStockLevel : Boolean?,
#SerializedName("hasArticlePrices") val hasArticlePrices : Boolean?,
#SerializedName("EstDeliveryDays") val estDeliveryDays : String?,
#SerializedName("hasOther") val hasOther : Boolean?,
#SerializedName("hasOutOfOrder") val hasOutOfOrder : Boolean?,
#SerializedName("hasWarning") val hasWarning : Boolean?,
#SerializedName("hasError") val hasError : Boolean?,
#SerializedName("flags") val flags : List<Flags>?,
#SerializedName("actionState") val actionState : String?,
#SerializedName("spareColumns") val spareColumns : List<SpareColumns>?
)
data class Flags (
#SerializedName("ErrorLevel") val errorLevel : Int?,
#SerializedName("ErrorFlag") val errorFlag : Int?,
#SerializedName("Translation") val translation : String?,
#SerializedName("BitPosition") val bitPosition : Int?
)
data class SpareColumns (
#SerializedName("key") val key : String?,
#SerializedName("value") val value : String?
)
RequestService Interface:
#GET(NetworkUtils.JSON_SERVICE_URL)
fun getStatus(#Header("guid") guid: String) : Call<StatsModel>
Method which process the response:
fun getStatusService(mandatorGuid: String, #Nullable statusCallbacks: ChartsCallbacks.StatsCallbacks) {
val mandatorItem = MandatorItem(mandatorGuid)
val guid: MutableMap<String, String> = HashMap()
guid["guid"] = mandatorItem.guid
var statusData: StatsModel.Stats?
val call: Call<StatsModel> = createAPI().getStatus(mandatorItem.guid)
call.enqueue(object : Callback<StatsModel> {
override fun onFailure(call: Call<StatsModel>, t: Throwable) {
Log.i("TEST", "Status failure: $t")
}
override fun onResponse(call: Call<StatsModel>, response: Response<StatsModel>) {
if (response.isSuccessful) {
statusData = response.body()!!.stats
Log.i("TEST", "ITEM $statusData")
statusCallbacks.onSuccess(statusData)
}
}
})
}
I only need the Stats data from the response!
But everytime I'm trying to do the request I'm getting this ERROR:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $
I know there are many posts on this subject but I couldn't find a solution to my problem. Any help would be appreciated!

android kotlin: storing retrieved data from url to room database

method i made:
private fun saveToRoom(albums: Array<Data>) {
doAsync {
/*val currentDBPath = getDatabasePath("albums_database").absolutePath
println("DBPath is " + currentDBPath)*/
var items = ArrayList<ProductList_Data>()
for (album in albums) {
val item = ProductList_Data()
item.name = album.name
item.price = album.price
items.add(item)
}
db?.productListDao()?.insert(items)
/*val musicAlbums = db?.productListDao()?.getAll()
activityUiThread {
longToast("Data Got saved")
refreshUIWith(musicAlbums!!)
}*/
}
}
this is data class names Data
data class Data(
val _links: Links?,
val attributes: List<Attribute>?,
val average_rating: String?,
val backordered: Boolean?,
val backorders: String?,
val backorders_allowed: Boolean?,
val button_text: String?,
val catalog_visibility: String?,
val categories: List<Category>?,
val cross_sell_ids: List<Any>?,
val custom_fields: CustomFields?,
val date_created: String?,
val date_created_gmt: String?,
val date_modified: String?,
val date_modified_gmt: String?,
val date_on_sale_from: Any?,
val date_on_sale_from_gmt: Any?,
val date_on_sale_to: Any?,
val date_on_sale_to_gmt: Any?,
val default_attributes: List<Any>?,
val description: String?,
val dimensions: Dimensions?,
val download_expiry: Int?,
val download_limit: Int?,
val downloadable: Boolean?,
val downloads: List<Any>?,
val external_url: String?,
val featured: Boolean?,
val grouped_products: List<Any>?,
val id: Int?,
val images: List<Image>?,
val manage_stock: Boolean?,
val menu_order: Int?,
val meta_data: List<MetaData>?,
val name: String?,
val on_sale: Boolean?,
val parent_id: Int?,
val permalink: String?,
val price: String?,
val price_html: String?,
val purchasable: Boolean?,
val purchase_note: String?,
val rating_count: Int?,
val regular_price: String?,
val related_ids: List<Int>?,
val reviews_allowed: Boolean?,
val sale_price: String?,
val shipping_class: String?,
val shipping_class_id: Int?,
val shipping_required: Boolean?,
val shipping_taxable: Boolean?,
val short_description: String?,
val sku: String?,
val slug: String?,
val sold_individually: Boolean?,
val status: String?,
val stock_quantity: Any?,
val stock_status: String?,
val tags: List<Any>?,
val tax_class: String?,
val tax_status: String?,
val total_sales: Int?,
val type: String?,
val upsell_ids: List<Any>?,
val variations: List<Int>?,
val virtual: Boolean?,
val weight: String?
) i want to get only name and price to be stored in room database
entity class that i am using :
#Entity(tableName = "productlisttable")
data class ProductList_Data(
#PrimaryKey
val uid: Int = 0,
#ColumnInfo(name = "_name")
var name: String? = "",
#ColumnInfo(name = "_price")
var price: String? = ""
)
calling method in main activity and getting red underline error that no values passed for init and all that
saveToRoom(Array<Data>))
i think the way i am calling the method is wrong or what
Use this function to convert and save array in database
#TypeConverter
fun fromStringList(stringList: List<String?>?): String? {
if (stringList == null) return null
val type = object : TypeToken<List<String?>?>() {}.type
return Gson().toJson(stringList, type)
}

Categories

Resources