Question Thembelani Mlalazi · Nov 14, 2017

How to Manipulate XML to Formatted String

I am using studio 2015 version which does not have dynamic objects and I need to read xml and convert that to a json I have managed to come close to json string but with little difficulties .I need to be able to identify the root element and specify where to put braces between objects  anyone  with any idea is welcome he is my code so far

ClassMethod WriteNodes(myfile As %String = "C:\Testdata\data.xml")
{
  set status=##class(%XML.TextReader).ParseFile(myfile,.textreader)
  
    if $$$ISERR(status)
      {
	    do $System.Status.DisplayError(status) 
	    quit
	  }

       set ptemp=##class(%Stream.FileCharacter).%New()
       set ptemp.Filename="C:\Testdata\ree.txt"
      //check status
     //iterate through document, node by node
  
       Do ptemp.Write( "{")
       while textreader.Read()
        {
           If (textreader.seq=462)
	         {
		       Do ptemp.Write("}")
		       Do ptemp.Write("]")
		       Do ptemp.Write("}")
		     }
		     
		       If ((textreader.Path="/[1]/[2]/[0]")&&(textreader.NodeType'= "endelement"))
	             {
		          Do ptemp.Write("{")
		         }
		            If ((textreader.Path="/[1]/[2]/[0]")&&(textreader.NodeType= "endelement"))
	                   {
		                Do ptemp.Write("},")
		              }
        
                   If ((textreader.Name'="")&&(textreader.NodeType'= "endelement"))
                      {
                        Do ptemp.Write($CHAR(34)_textreader.Name_$CHAR(34)_$CHAR(58))
                      }
                      Else
                      {
	                   Do ptemp.Write("")
	                  }
           
                  If (textreader.Value'="")
                     {
                      Do ptemp.Write($CHAR(34)_textreader.Value_$CHAR(34)_"," )
                     }
               Do ptemp.WriteLine()
        }

       Do ptemp.%Save()
       
       quit
}

Comments

Thembelani Mlalazi  Nov 14, 2017 to Robert Cemper

@Robert Cemper thank you but I am trying to avoid using the object classes to create this as I will be processing a lot of  different files and will end up with a lot of classes

0
Robert Cemper  Nov 15, 2017 to Robert Cemper

If you don't want / need the content as object and just want to convert XML2JSON
why wasting time and energy to re-invent the wheel an not just using any of the many downloadable tools
and call them over $ZF(-2)  and consume the result ?
Google gave my some thousand hits of tested solutions e.g. https://github.com/sinelaw/xml-to-json

I mean it's doable with Caché but file_in => file_out is not more than a nice exercise for training.
 

0
Marc Mundt  Nov 14, 2017 to Thembelani Mlalazi

%ZEN.Auxiliary.jsonProvider can make use of %ZEN.proxyObject to represent the JSON. This wouldn't require a formal class definition for your objects.

0
Robert Cemper  Nov 14, 2017 to Marc Mundt

Thanks, totally correct!
It's mentioned in line 5 of the doc I pointed to.

0
John Murray  Nov 15, 2017 to Thembelani Mlalazi

@Thembelani Mlalazi - when mentioning a DC member in a post it looks like you're copying and pasting the member name in a way that carries over a hyperlink. That hyperlink markup seems to prevent the DC software from recognizing the user. I recommend using the Preview button as a way of checking that the "mention" syntax is correct.

In any case it may be overkill to mention someone who has already contributed to the thread, since they typically get notified of updates unless they have deliberately unsubscribed.

0
Marc Mundt  Nov 15, 2017 to Thembelani Mlalazi

Here's a sample for creating a proxy object and outputting it as JSON:

Set tProxy = ##class(%ZEN.proxyObject).%New()
Set tProxy.Property1 = "Some value 1"
Set tProxy.Property2 = "Some value 2"
Set tSC=##class(%ZEN.Auxiliary.jsonProvider).%WriteJSONStreamFromObject(.tStream,.tProxy)
Write "Result (blank means no error):",$System.Status.GetErrorText(tSC),!
Write "JSON output:",!
Do tStream.OutputToDevice()

This produces the following output:

Result (blank means no error):
JSON output:
{
        "Property1":"Some value 1",
        "Property2":"Some value 2"
}
0
Murillo Braga  May 6, 2020 to Marc Mundt

Hi there Marc,

Do you know whether is there anything to perform the opposite (convert an object into a xml string)?

E.g: 

Class BaseClass.Harvest Extends (%SerialObject, %XML.Adaptor) [ ProcedureBlock ]
{
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

0
Thembelani Mlalazi  Nov 15, 2017 to Marc Mundt

@Marc Mundt I have read around the topic but still cannot figure out how to read an xml to %ZEN.proxyObject would mind please giving us an example to work with I am  still new to this thank you

0