Written by

Senior Integration Specialist at EskoSystems
Question Kari Vatjus-Anttila · Oct 31, 2016

Importing XML to a Caché Object

Hi,

I'm new with writing Caché Objectscript so I need some assistance. I have XML which contains information like this:

<?xml version="1.0" encoding="UTF-8"?>
<session>
   <sessionId>124364</sessionId>
   <cabinet>demo</cabinet>
   <eventType>IN</eventType>
   <eventTime>20161006160154</eventTime>
   <login>test</login>
   <loginFirstName>test</loginFirstName>
   <loginLastName>test</loginLastName>
</session>

I have a class representing this object as follows:

Class Testing.Messages.Session Extends (%RegisteredObject, %XML.Adaptor, Ens.Request){Parameter XMLNAME = "session";/// Session identifierProperty sessionId As %String;/// Warehouse identifierProperty cabinet As %String;/// Event typeProperty eventType As %String;/// Event time stampProperty eventTime As %String;/// User identifierProperty login As %String;/// User firstnameProperty loginFirstName As %String;/// User lastnameProperty loginLastName As %String;}

And finally the source code which I use to import that XML discussed first to the message object presented second.

Method handleSession(pRequest As %CharacterStream) As %Status{Set status = $$$OK// Get the CDATA content of this message. Contains XML discussed previouslySet messagedata = ..getContent(pRequest)Set reader = ##class(%XML.Reader).%New() Set status = reader.OpenString(messagedata) Do reader.Rewind() If $$$ISERR(status) {do $System.Status.DisplayError(status)}// Associate a class name with the XML element nameDo reader.CorrelateRoot("Testing.Messages.Session")// Read objects from xml dataWhile (reader.Next(.tMessage,.status)) {  Write tMessage.Name,!}If $$$ISERR(status) {do $System.Status.DisplayError(status)}$$$LOGINFO("Debug: " _tMessage)$$$LOGINFO("Debug: " _tMessage.sessionId)$$$LOGINFO("Debug: " _tMessage.cabinet)$$$LOGINFO("Debug: " _tMessage.eventType)$$$LOGINFO("Debug: " _tMessage.eventTime)$$$LOGINFO("Debug: " _tMessage.login)$$$LOGINFO("Debug: " _tMessage.loginFirstName)$$$LOGINFO("Debug: " _tMessage.LoginLastName)// Send the message to the preprocessordo ..SendRequestSync("MessagePreProcessor",.tMessage,.tResponse) Quit $$$OK}

For whatever reason this does not work. I guess the error happens inside the while loop when I iterate through the XML data but no error messages are thrown. It just fails silently.

Any ideas where should I look to fix this?

Comments

Eduard Lebedyuk · Oct 31, 2016

This line causes an error:

Write tMessage.Name,!

Your class does not have Name property, so it causes an error.

The following method works :

/// Do ##class(Testing.Messages.Session).test()
ClassMethod test()
{
    Set messagedata = "<?xml version=""1.0"" encoding=""UTF-8""?><session><sessionId>124364</sessionId><cabinet>demo</cabinet><eventType>IN</eventType><eventTime>20161006160154</eventTime><login>test</login><loginFirstName>test</loginFirstName><loginLastName>test</loginLastName></session>"
    Set reader = ##class(%XML.Reader).%New()
    Set status = reader.OpenString(messagedata)
    Do reader.Rewind()

    If $$$ISERR(status) {do $System.Status.DisplayError(status)}

    // Associate a class name with the XML element name
    Do reader.CorrelateRoot("Testing.Messages.Session")

    // Read objects from xml data
    While (reader.Next(.tMessage,.status)) {
        Do:$$$ISERR(status) $System.Status.DisplayError(status)
        Write tMessage.sessionId,!
    }
}

Terminal:

USER >do ##class(Testing.Messages.Session).test()
124364
0
Kari Vatjus-Anttila  Nov 1, 2016 to Eduard Lebedyuk

Thanks for the input, it was obvious when somebody else pointed it out.  I managed to import that sample XML to that object!

Cheers

0
Krishnaveni Kapu  Jul 25, 2024 to Eduard Lebedyuk

what If my xml is as below :

<?xml version="1.0" encoding="UTF-8"?>
<session>
   <session_Id>124364</session_Id>   
</session>

how do I read session_Id ?

as the xml tag has an underscore , it throws an error always.

0
Robert Cemper  Jul 25, 2024 to Krishnaveni Kapu

Using my previous reply you can do this without need of any custom object:

SAMPLES>read xml
<?xml version="1.0" encoding="UTF-8"?> <session> <session_Id>124364</session_Id> </session>
SAMPLES>set rdr=##class(%XML.Reader).%New()
SAMPLES>do rdr.OpenString(xml)
SAMPLES>zwrite%SAX=1%SAX(1)=2%SAX(1,0)=""%SAX(1,1)="1"""%SAX(1,2)="!>A"%SAX(1,"N","http://www.w3.org/2001/XMLSchema-instance")=1%SAX(1,"d")=4%SAX(1,"d",1)="session"%SAX(1,"d",2)=" "%SAX(1,"d",3)="session_Id"%SAX(1,"d",4)=124364%SAX(1,"n")=1%SAX(1,"n",1)="http://www.w3.org/2001/XMLSchema-instance"%SAX(1,"v")=6
rdr=<OBJECT REFERENCE>[1@%XML.Reader]
xml="<?xml version="1.0" encoding="UTF-8"?> <session> <session_Id>124364</session_Id> </session>"
SAMPLES>
0
Enrico Parisi  Jul 25, 2024 to Krishnaveni Kapu

Property sessionId As %String(XMLNAME="session_id";

0