· Aug 4, 2021

Convert a %String property with CDATA and XML content to Ensemble object

Hello, first of all thanks for your time reading this question ◀️

We would need to achieve the following task:

We have a Ens.Response message with this structure:

<?xml version="1.0" ?>
<!-- type: Mensajes.Response.Justicia.PLATINO.EnviarIniciadoresGeneralResponse  id: 10986665 -->
        <![CDATA[<?xml version="1.0" encoding="ISO-8859-1"?>
<mensajeWS xmlns="https://wslexnet.webservices.lexnet/3.22"><respuestaEnvioMensaje xmlns=""><idEnvio>1947625809</idEnvio><tamBloque>524288</tamBloque><bytesMIME>TFgDBA...</bytesMIME></respuestaEnvioMensaje></mensajeWS>]]>

The content inside the CDATA represent a XML message:

<?xml version="1.0" encoding="ISO-8859-1"?>
<mensajeWS xmlns="https://wslexnet.webservices.lexnet/3.22">
    <respuestaEnvioMensaje xmlns="">


We wonder how could we convert the %String property EnviarIniciadoresGeneralOut to an Ensemble object


We have developed the code as follows:


Class Operaciones.XML.Justicia.TransformacionesJusticia Extends Ens.BusinessOperation [ ProcedureBlock ]

Parameter INVOCATION = "Queue";

// ClassMethod generarEnviarIniciadoresGeneralJusticia(pRequest As Mensajes.Response.Justicia.PLATINO.EnviarIniciadoresGeneralResponse, Output pResponse As EsquemasDatos.Justicia.respuestaEnvioMensajeType) As %Status

/// Lo creamos el 04 08 21 para convertir String a EsquemasDatos en XML
ClassMethod generarEnviarIniciadoresGeneralJusticia(pRequest As Mensajes.Response.Justicia.PLATINO.EnviarIniciadoresGeneralResponse, Output pResponse As Mensajes.Response.Justicia.PLATINO.EnviarIniciadoresGeneralEstructuradoResponse) As %Status
    $$$LOGINFO("Entra en: Operaciones.XML.Justicia.TransformacionesJusticia.generarEnviarIniciadoresGeneralJusticia: ")
    // WRITE ##class(Operaciones.XML.Justicia.TransformacionesJusticia).generarEnviarIniciadoresGeneralJusticia("<?xml version="1.0" encoding="ISO-8859-1"?><mensajeWS xmlns="https://wslexnet.webservices.lexnet/3.22">    <respuestaEnvioMensaje xmlns="">        <idEnvio>1187808872</idEnvio>        <tamBloque>524288</tamBloque>        <bytesMIME>TFgDBA</bytesMIME>    </respuestaEnvioMensaje></mensajeWS>")
    set pResponse = ##class(Mensajes.Response.Justicia.PLATINO.EnviarIniciadoresGeneralEstructuradoResponse).%New()
    #dim tDocument as %XML.XPATH.Document
    #dim tResultList as %ListOfObjects
    $$$LOGINFO("pRequest.EnviarIniciadoresGeneralOut: "_pRequest.EnviarIniciadoresGeneralOut)

     Set tSC=##class(%XML.XPATH.Document).CreateFromStream(pRequest.EnviarIniciadoresGeneralOut,.tDocument)
     If $$$ISERR(tSC) Do $System.OBJ.DisplayError(tSC)
     //set expresion="respuestaEnvioMensaje"
     //set expresion="text()"
     set expresion="*"
     set contexto="/mensajeWS"
     set tSC = tDocument.EvaluateExpression(contexto,expresion,.tResultList)
    set contador= tResultList.Count()
    /// ¿Por qué sale contrador = 0?
    $$$LOGINFO("contador es: "_contador)

    if (contador>0){
         for index=1:1:tResultList.Count() {
             set element = tResultList.GetAt(index)
             while (element.Read()){
                 if ((element.Name = "idEnvio") && (element.NodeType = "element")){
                    do element.Read()
                    set pResponse.EnviarIniciadoresGeneralOut.idEnvio = element.Value
                 if ((element.Name = "tamBloque") && (element.NodeType = "element")){
                    do element.Read()
                    set pResponse.EnviarIniciadoresGeneralOut.tamBloque = element.Value
                 if ((element.Name = "bytesMIME") && (element.NodeType = "element")){
                    do element.Read()
                    set pResponse.EnviarIniciadoresGeneralOut.bytesMIME = element.Value
     Quit $$$OK



We call it from a BPL as:

set tSC = ##class(Operaciones.XML.Justicia.TransformacionesJusticia).generarEnviarIniciadoresGeneralJusticia(context.enviarIniciadoresGeneralResponse, .respuesta)


However with the $$$LOGINFO, we observe: "contador es: 0"

Which means we are not collecting the contents inside the following XML Path: /mensajeWS/respuestaEnvioMensaje


We have tried with the 3 following ways:

     //set expresion="respuestaEnvioMensaje"
     //set expresion="text()"
     set expresion="*"

In all cases it shows:

     contador es: 0

Which means tResultList is empty and we do not iterate inside our for and while


➡️ How would you recommend us to convert a string with XML content to an Ensemble object💭

Thanks for your replies


We have read:


Thanks for your help  🙏

➡️➡️ How would you recommend us to convert a string with XML content to an Ensemble object? 💭

$ZV: Cache for UNIX (Red Hat Enterprise Linux for x86-64) 2017.2.1 (Build 801_3_18358U) Tue Jul 24 2018 16:36:10 EDT
Discussion (2)1
Log in or sign up to continue

First you need to create corresponding classed. You can do that by either importing the XSD or manually.

Here's a manual approach:

Class test.mensajeWS Extends (%RegisteredObject, %XML.Adaptor) {

Parameter NAMESPACE = "https://wslexnet.webservices.lexnet/3.22";

Property respuestaEnvioMensaje As respuestaEnvioMensaje;

Class test.respuestaEnvioMensaje Extends (%RegisteredObject, %XML.Adaptor) {

Property idEnvio As %Integer;

Property tamBloque As %Integer;

Property bytesMIME As %VarString;

After that in your BS convert incoming XML string like this:

set reader = ##class(%XML.Reader).%New()
set sc = reader.OpenString(pRequest.EnviarIniciadoresGeneralOut)
quit:$$$ISERR(sc) sc

do reader.Correlate("mensajeWS","test.mensajeWS")

do reader.Next(.mensajeWSObj,.sc)
quit:$$$ISERR(sc) sc

// Process mensajeWSObj