androidxmlkotlinsimple-framework

Kotlin + SimpleXMLElement + Map sublist element


I'm developing an Android App with Kotlin. I need to consume an API that returns an XML to a request.

For example the returned XML is:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <soap:Body>
      <ListaEmpresasResponse xmlns="http://example.com/">
         <ListaEmpresasResult>
            <IdEstado>001</IdEstado>
            <Mensaje/>
            <Empresas>
               <Empresa>
                  <IdEmpresas>1</IdEmpresas>
                  <Nombre>Test 1</Nombre>
               </Empresa>
               <Empresa>
                  <IdEmpresas>2</IdEmpresas>
                  <Nombre>Test2</Nombre>
               </Empresa>
               <Empresa>
                  <IdEmpresas>4</IdEmpresas>
                  <Nombre>Test 3</Nombre>
               </Empresa>
               <Empresa>
                  <IdEmpresas>5</IdEmpresas>
                  <Nombre>Test 4</Nombre>
               </Empresa>
            </Empresas>
         </ListaEmpresasResult>
      </ListaEmpresasResponse>
   </soap:Body>
</soap:Envelope>

I'm able to parse the IdEstado and Mensaje fields but i need to create a list with the elements called "Empresa".

I have file called mapper.kt

interface Mapper<in R, out T> {

    fun transform(input: R): T
    fun transformList(inputList: List<R>): List<T>

}

I have a file called DatosTrabajoResponseEmpresaEntityMapper.kt

import com.example.smt.data.model.datostrabajo.DatosTrabajoResponseEmpresaEntity
import com.example.smt.data.model.datostrabajo.DatosTrabajoResponseEmpresaEntityEmpresa
import com.example.smt.data.model.datostrabajo.DatosTrabajoResponseEmpresaEnvelope
import com.example.smt.data.model.datostrabajo.Empresa
import kotlinx.android.synthetic.main.activity_datostrabajo.view.*

class DatosTrabajoResponseEmpresaEntityMapper: Mapper<DatosTrabajoResponseEmpresaEnvelope, DatosTrabajoResponseEmpresaEntity> {

    override fun transform(input: DatosTrabajoResponseEmpresaEnvelope): DatosTrabajoResponseEmpresaEntity {
        return DatosTrabajoResponseEmpresaEntity(
            input.body!!.listaEmpresasResponse!!.listaEmpresasResult!!.resultCode,
            input.body!!.listaEmpresasResponse!!.listaEmpresasResult!!.message,
            null<-- This is where i should parse the sublist where i'm not able to.
        )
    }




    override fun transformList(inputList: List<DatosTrabajoResponseEmpresaEnvelope>): List<DatosTrabajoResponseEmpresaEntity> {
        return inputList.map { transform(it) }
    }

}

class DatosTrabajoResponseEmpresaEntityMapperEmpresa: Mapper<Empresa, DatosTrabajoResponseEmpresaEntityEmpresa>{
    override fun transform(input: Empresa): DatosTrabajoResponseEmpresaEntityEmpresa {
        return DatosTrabajoResponseEmpresaEntityEmpresa(
            input.idEmpresas,
            input.nombre
        )
    }

    override fun transformList(inputList: List<Empresa>): List<DatosTrabajoResponseEmpresaEntityEmpresa> {
        return inputList.map { transform(it) }
    }
}

My response file DatosTrabajoResponseEmpresa.kit where i have the structure defined is:

import org.simpleframework.xml.Element
import org.simpleframework.xml.Namespace
import org.simpleframework.xml.NamespaceList
import org.simpleframework.xml.Root
import org.simpleframework.xml.ElementList



@Root(name = "soap:Envelope")
@NamespaceList(
    Namespace(prefix = "soap", reference = "http://schemas.xmlsoap.org/soap/envelope/"),
    Namespace(prefix = "xsi", reference = "http://www.w3.org/2001/XMLSchema-instance"),
    Namespace(prefix = "xsd", reference = "http://www.w3.org/2001/XMLSchema")
)
class DatosTrabajoResponseEmpresaEnvelope {
    @field:Element(name = "Body", required = false)
    var body: DatosTrabajoResponseEmpresaBody? = null
}

@Root(name = "soap:Body", strict = false)
class DatosTrabajoResponseEmpresaBody {
    @field:Element(name = "ListaEmpresasResponse", required = false)
    var listaEmpresasResponse: ListaEmpresasResponse? = null
}

@Root(name = "ListaEmpresasResponse", strict = false)
class ListaEmpresasResponse {
    @field:Element(name = "ListaEmpresasResult", required = false)
    var listaEmpresasResult: ListaEmpresasResult? = null
}

@Root(name = "ListaEmpresasResult", strict = false)
class ListaEmpresasResult {
    @field:Element(name = "IdEstado", required = false)
    var resultCode: String? = null

    @field:Element(name = "Mensaje", required = false)
    var message: String? = null

    @field:ElementList(name = "Empresas", required = false)
    var empresas: List<Empresa>? = null

}

@Root(name = "Empresa", strict = false)
class Empresa {
    @field:Element(name = "IdEmpresas", required = false)
    var idEmpresas: Int? = null

    @field:Element(name = "Nombre", required = false)
    var nombre: String? = null
}

And at last this is my entity file DatosTrabajoResponseEmpresaEntity.kt:

import android.annotation.SuppressLint
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize

@SuppressLint("ParcelCreator")
@Parcelize
data class DatosTrabajoResponseEmpresaEntityEmpresa(
    val idEmpresas: Int?,
    val nombre: String?
) : Parcelable

@SuppressLint("ParcelCreator")
@Parcelize
data class DatosTrabajoResponseEmpresaEntity(
    val resultCode: String?,
    val message: String?,
    val empresas: List<DatosTrabajoResponseEmpresaEntityEmpresa?>
) : Parcelable

At the end what i expect is to have an attribut in my entity with the list List my problem is that i tried to parse it but not able. I would appreciate any help.


Solution

  • I think i found the solution:

    input.body!!.listaEmpresasResponse!!.listaEmpresasResult!!.empresas!!.map { it  }.map{ DatosTrabajoResponseEmpresaEntityEmpresa(it.idEmpresas, it.nombre) }