XML string to Serial Object
Hello.
I want to know how can I convert XML String intro a %SerialObject.
This is an example:
<Envelope>
<Body>
<RESULT>
<SUCCESS>TRUE</SUCCESS>
<LIST>
<ID>11111</ID>
<NAME>one</NAME>
</LIST>
<LIST>
<ID>22222</ID>
<NAME>two</NAME>
</LIST>
</RESULT>
</Body>
</Envelope>
<Body>
<RESULT>
<SUCCESS>TRUE</SUCCESS>
<LIST>
<ID>11111</ID>
<NAME>one</NAME>
</LIST>
<LIST>
<ID>22222</ID>
<NAME>two</NAME>
</LIST>
</RESULT>
</Body>
</Envelope>
And this are the %SerialObject classes I have created:
Class test.Envelope Extends (%SerialObject,%XML.Adaptor)
{
Property Body As test.Body;
}
{
Property Body As test.Body;
}
Class test.Body Extends (%SerialObject,%XML.Adaptor)
{
Property RESULT As test.Result;
}
{
Property RESULT As test.Result;
}
Class test.Result Extends (%SerialObject,%XML.Adaptor)
{
Property SUCCESS As %String(MAXLEN = "");
Property LIST As list Of test.List;
}
{
Property SUCCESS As %String(MAXLEN = "");
Property LIST As list Of test.List;
}
Class test.List Extends (%SerialObject,%XML.Adaptor)
{
Property ID As %String(MAXLEN = "");
Property NAME As %String(MAXLEN = "");
}
{
Property ID As %String(MAXLEN = "");
Property NAME As %String(MAXLEN = "");
}
I have tested with a function like this:
set reader = ##class(%XML.Reader).%New()
set sc = reader.OpenStream(xmlStream)
do reader.Rewind()
do reader.CorrelateRoot("test.Envelope")
while (reader.Next(.tMessage,.sc)) {
set OUT = tMessage
}
set sc = reader.OpenStream(xmlStream)
do reader.Rewind()
do reader.CorrelateRoot("test.Envelope")
while (reader.Next(.tMessage,.sc)) {
set OUT = tMessage
}
But it only works if property "LIST" is a single object and not a list of objects. When I try with the list, I get this error:
ERROR #6237: Unexpected tag in XML input: LIST (ending at line 6 character 5).
How can I convert a XML String into a SerialObject?
Thank you in advance.
Maybe is there something like ##class(Ens.Util.JSON).JSONStreamToObject(...)?
Laura Blázquez you can do that with JSON because JSON is schema less but XML objects need a schema in a explicit or implicit way you need to define how the object is represented by the XML notation and viceversa.
It's not a bad question, but the short answer is not in a single line of code.
Take a look at this post, it might give you a few ideas if you just wanted a Dynamic Object...
https://community.intersystems.com/post/xml-json-conversion
Thank you very much, it works now!
Thank you very much! I have tested this, and it's easier to create the full structure with this. This is very useful to us
Default XMLPROJECTION for collection properties is WRAPPED, which adds wrapping tag.
Define your list property this way:
Laura,
there is something like .....
Ens.Util.XML.Reader
especially ##class(Ens.Util.XML.Reader).ObjectFromString(. . . )
But you have to fix ther error pointed out by @Eduard Lebedyuk anyhow
Hi Laura,
I find it simpler to write an XSD (even if you don't have one) and then use the XML code generator wizard.
A good place to start is by using an online tool that will auto generate an XSD from XML for you, such at the one you can find here...
https://www.liquid-technologies.com/online-xml-to-xsd-converter
Sometimes you will need to massage the XML a little first, for instance add a second instance of an element when you only have one in your example and you know there will be many.
So you would end up with an XSD that looks like this...
Save this to a file and from studio select "Tools" from the main menu, then "add-ins" and then "XML Schema Wizard" which might be visible or you might need to click "add-ins" again to bring it into focus.
Select the file, click next, de-select the "Create Persistent Classes" option and type in a package name, click next and select "Serial" for each of the classes, click next and the classes will be generated. You might need to go and compile them before they can be used. The generated code looks like this...
And here is the solution in action...
Hi there Sean,
Do you know whether is there anything to perform the opposite (convert an object into a xml string)?
E.g:
{
Parameter ELEMENTQUALIFIED = 1;
...
Property Number As %String(MAXLEN = "", XMLNAME = "Number");
Property PatientNumber As %String(MAXLEN = "", XMLNAME = "PatientNumber");
...
Outcome would be:
<xml>
<Harvest>
<Number></Number>
<PatientNumber></PatientNumber>
...
Many thanks
Social networks
InterSystems resources
Log in or sign up
Log in or create a new account to continue
Log in or sign up
Log in or create a new account to continue
Log in or sign up
Log in or create a new account to continue