Question
· Mar 12

Best way to translate a XML String to an Ens.Response derived class?

Hello,
First of all thanks for your time and help with this question.

We wonder how could we convert a String which represents an XML, to a class which extends from Ens.Response

Our context is a REST Operation, where we currently split the String with $PIECE and set each propertie as follows:

        set codigo = $PIECE($PIECE(httpResponse,"<error><codigo>",2),"</codigo><descripcion>",1)
        set descripcion = $PIECE($PIECE(httpResponse,"<descripcion>",2),"</descripcion>",1)
        set codigoSERAM = $PIECE($PIECE(httpResponse,"</error><codigo>",2),"</codigo></resultado>",1)
        
        set pResponse = ##class(Mensajes.Response.Radiologia.NumeroOrdenAcodigoSERAMResponse).%New()
        set pResponse.resultado =  ##class(EsquemasDatos.Radiologia.Resultado).%New()
        set pResponse.resultado.error =  ##class(EsquemasDatos.Seguridad.Error).%New()
        set pResponse.resultado.error.codigo = codigo
        set pResponse.resultado.error.descripcion = descripcion
        set pResponse.resultado.codigo = codigoSERAM


Is there any recommended way to convert the XML String which has the following look:

    <resultado>
        <error>
            <codigo>0</codigo>
            <descripcion>Proceso realizado correctamente</descripcion>
        </error>
        <codigo>06050301</codigo>
    </resultado>


    
To the Ens.Response derived class which structure is:

Class Mensajes.Response.Radiologia.NumeroOrdenAcodigoSERAMResponse Extends Ens.Response
{

Property resultado As EsquemasDatos.Radiologia.Resultado;
Class EsquemasDatos.Radiologia.Resultado Extends (%SerialObject, %XML.Adaptor) [ ProcedureBlock ]
{

Property error As EsquemasDatos.Seguridad.Error;
Property codigo As %String(MAXLEN = "");
Class EsquemasDatos.Seguridad.Error Extends (%Persistent, %XML.Adaptor, %JSON.Adaptor) [ ClassType = persistent, ProcedureBlock ]
{

Property codigo As %Numeric;
Property descripcion As %String(MAXLEN = "");

I

 

f the String written in the response would be a JSON we could do:

        set tSC= claseAux.%ConvertJSONToObject(httpRequest.HttpResponse.Data,"Mensajes.Response.Radiologia.NumeroOrdenAcodigoSERAMResponse",.pResponse,1)    


Or we could use something like:

    ##class(%JSON.Adaptor).%JSONImport(input, %mappingName As %String = "")


    

But what is the recommended way to parse XML String to Ens.Response?

Thanks for your time, help and support.

Thank you.

Product version: IRIS 2020.1
Discussion (5)3
Log in or sign up to continue

To export a XML enabled class use %XML.Writer class.

ClassMethod test()
{
	Set message=##class(Mensajes.Response.Radiologia.NumeroOrdenAcodigoSERAMResponse).%New()
	Set message.resultado.codigo="06050301"
	Set message.resultado.error=##class(EsquemasDatos.Seguridad.Error).%New()
	Set message.resultado.error.codigo=0
	Set message.resultado.error.descripcion="Proceso realizado correctamente"
	
	Set writer=##class(%XML.Writer).%New()
	Set writer.Indent=1

	Set sc=writer.OutputToString()
	; handle sc error here
	Set sc=writer.RootObject(message.resultado)
	; handle sc error here
	Set string=writer.GetXMLString()
	Write string,!
	Quit $$$OK
}

In your EsquemasDatos.Radiologia.Resultado class add XMLNAME parameter to obtain the correct (lowercase) tag name:

Class EsquemasDatos.Radiologia.Resultado Extends (%SerialObject, %XML.Adaptor)
{

Parameter XMLNAME = "resultado";

Property error As EsquemasDatos.Seguridad.Error;

Property codigo As %String(MAXLEN = "");

Result:

Do ##class(Mensajes.Response.Radiologia.NumeroOrdenAcodigoSERAMResponse).test()
<resultado>
  <error>
    <codigo>0</codigo>
    <descripcion>Proceso realizado correctamente</descripcion>
  </error>
  <codigo>06050301</codigo>
</resultado>

OK, you asked XML string to object 😊

ClassMethod test()
{
	Set message=##class(Mensajes.Response.Radiologia.NumeroOrdenAcodigoSERAMResponse).%New()
	Set message.resultado.codigo="06050301"
	Set message.resultado.error=##class(EsquemasDatos.Seguridad.Error).%New()
	Set message.resultado.error.codigo=0
	Set message.resultado.error.descripcion="Proceso realizado correctamente"
	
	Set writer=##class(%XML.Writer).%New()
	Set writer.Indent=1

	Set sc=writer.OutputToString()
	; handle sc error here
	Set sc=writer.RootObject(message.resultado)
	; handle sc error here
	Set string=writer.GetXMLString()
	Write string,!
	
	; convert XML string back to object
    Set reader = ##class(%XML.Reader).%New()
    Set sc=reader.OpenString(string)
    ; handle sc error here
    Do reader.Correlate("resultado","EsquemasDatos.Radiologia.Resultado")
    Do reader.Next(.ReturnObject,.sc)
    ; handle sc error here
    Write "ReturnObject is of type ",ReturnObject.%ClassName(1),!
    do ReturnObject.XMLExport(,",indent")
	
	Quit
}

Result:

Do ##class(Mensajes.Response.Radiologia.NumeroOrdenAcodigoSERAMResponse).test()
<resultado>
  <error>
    <codigo>0</codigo>
    <descripcion>Proceso realizado correctamente</descripcion>
  </error>
  <codigo>06050301</codigo>
</resultado>
 
ReturnObject is of type EsquemasDatos.Radiologia.Resultado
<resultado>
  <error>
    <codigo>0</codigo>
    <descripcion>Proceso realizado correctamente</descripcion>
  </error>
  <codigo>06050301</codigo>
</resultado>

In fact, for simple XML export (no namespace and other amenities) you can just use XMLExport*() methods.

ClassMethod test()
{
	Set message=##class(Mensajes.Response.Radiologia.NumeroOrdenAcodigoSERAMResponse).%New()
	Set message.resultado.codigo="06050301"
	Set message.resultado.error=##class(EsquemasDatos.Seguridad.Error).%New()
	Set message.resultado.error.codigo=0
	Set message.resultado.error.descripcion="Proceso realizado correctamente"
	
	Set sc=message.resultado.XMLExportToString(.string)
    ; handle sc error here

	Write string,!!
	
	; convert XML string back to object
    Set reader = ##class(%XML.Reader).%New()
    Set sc=reader.OpenString(string)
    ; handle sc error here
    Do reader.Correlate("resultado","EsquemasDatos.Radiologia.Resultado")
    Do reader.Next(.ReturnObject,.sc)
    ; handle sc error here
    Write "ReturnObject is of type ",ReturnObject.%ClassName(1),!
    do ReturnObject.XMLExport(,",indent")
	
	Quit
}

Result:

Do ##class(Mensajes.Response.Radiologia.NumeroOrdenAcodigoSERAMResponse).test()
<resultado><error><codigo>0</codigo><descripcion>Proceso realizado correctamente</descripcion></error><codigo>06050301</codigo></resultado>
 
ReturnObject is of type EsquemasDatos.Radiologia.Resultado
<resultado>
  <error>
    <codigo>0</codigo>
    <descripcion>Proceso realizado correctamente</descripcion>
  </error>
  <codigo>06050301</codigo>
</resultado>