Function to convert JSON to XML

275 views
Skip to first unread message

jan.sp...@grecoavalon.com

unread,
May 19, 2021, 6:31:51 PM5/19/21
to harbou...@googlegroups.com

Hi all:

 

Maybe the following function I wrote (which converts JSON to XML) can be useful to somebody.

I´m not expert in JSON but I have some JSON files, I´ve tested it and it works so far.

Maybe there are out there some other JSON nuances I don’t know, but it covers a lot, and it’s recursive, so it supports any nested levels.

Call it like this:

r  := CONVERT_JSON_XML(s,0,'root') //s=JSON string, r=XML output

 

STATIC FUNCTION JSON_SEEK_CHAR(s,xStart,xCharSet)

Local jPos

jPos := xStart

Do While AT(SubStr(s,jPos,1),xCharSet) = 0 .AND. jPos < Len(s)

   jPos := jPos + 1

EndDo

RETURN jPos

 

 

STATIC FUNCTION JSON_JUMP_CHARS(s,xStart,xCharSet)

Local jPos

jPos := xStart

Do While AT(SubStr(s,jPos,1),xCharSet) <> 0 .AND. jPos < Len(s)

   jPos := jPos + 1

EndDo

RETURN jPos

 

 

STATIC FUNCTION JSON_GET_MATCHING_DELIMITER(s,xStart,xChar1,xChar2)

Local xL,jPos

xL   := 1

jPos := xStart

Do While .T.

   If jPos = Len(s)

      EXIT

   EndIf

   If SubStr(s,jPos,1) = xChar2

      xL := xL - 1

   EndIf

   If SubStr(s,jPos,1) = xChar1

      xL := xL + 1

   EndIf

   If xL = 0

      EXIT

   EndIf

   jPos := jPos + 1

EndDo

RETURN jPos

 

 

 

FUNCTION CONVERT_JSON_XML(sJSon,xNivel,xPrevious)

Local xPos1,xPos2,xPos3,xPos4,xPos5,xPos6,xPos7,xPosX

Local s,result,s2,xID,xFPos,r,x

If xNivel > 100

   RETURN '***ERROR: Recursive Depth exceeded***'

EndIf

result := ''

s2     := sJSon

Do While .T.

   If AT('"',s2) > 0 //Some info still left to process?

      xPos3 := JSon_Seek_Char(s2,1,'"{')

      Do Case

         Case SubStr(s2,xPos3,1) = '"' //It's an element...

              xPos4 := JSon_Seek_Char(s2,xPos3+1,'"')

              xID   := SubStr(s2,xPos3+1,(xPos4-xPos3)-1)

              xPos5 := JSon_Seek_Char(s2,xPos4+1,':')

              xPos6 := JSon_Jump_Chars(s2,xPos5+1,' '+CRLF+TAB)

         Case SubStr(s2,xPos3,1) = '{' //It's a set of iterations...

              xID   := IIF(xPrevious = NIL,'???',xPrevious)

              xPos6 := xPos3

      EndCase

      xPosX := JSon_Seek_Char(s2,xPos6+1,'"{')

      Do Case

         Case SubStr(s2,xPos6,1) = '[' .AND. SubStr(s2,xPosX,1) = '"' //It's a sequence like ["01","02","03"]

              xPos7 := JSon_get_matching_Delimiter(s2,xPos6+1,'[',']')

              s3    := SubStr(s2,xPos6+1,(xPos7-xPos6)-1)

              xFPos := xPos7+1

              x := 1

              Do While .T.

                 r := GetPartStr(s3,",",x)

                 r := StrTran(r,'"','') //Clean up...

                 If Len(AllTrim(r)) = 0

                    EXIT

                 EndIf

                 result := result + Space(xNivel*5)+'<'+xID+'>'+r+'</'+xID+'>'+CRLF

                 x := x + 1

              EndDo

         Case AT(SubStr(s2,xPos6,1),'0123456789.') <> 0 //It's a numeric Value...

              xPos7  := Json_Seek_Char(s2,xPos6,' ,}'+CRLF)

              xValue := SubStr(s2,xPos6,(xPos7-xPos6))

              result := result + Space(xNivel*5)+'<'+xID+'>'+xValue+'</'+xID+'>'+CRLF

              xFPos  := xPos7

         Case SubStr(s2,xPos6,1) = '"' //It's alphanumeric data...

              xPos7  := Json_Seek_Char(s2,xPos6+1,'"')

              xValue := SubStr(s2,xPos6+1,(xPos7-xPos6)-1)

              result := result + Space(xNivel*5)+'<'+xID+'>'+xValue+'</'+xID+'>'+CRLF

              xFPos  := xPos7

         Case SubStr(s2,xPos6,1) = '{' //It's a set of iterations...

              xPos7  := JSon_get_matching_Delimiter(s2,xPos6+1,'{','}')

              s3     := SubStr(s2,xPos6+1,(xPos7-xPos6)+1-1-1)

              xFPos  := xPos7

              result := result + Space(xNivel*5)+'<'+xID+'>'+CRLF

              r := CONVERT_JSON_XML(s3,xNivel+1,NIL)

              result := result + r

              result := result + Space(xNivel*5)+'</'+xID+'>'+CRLF

         Case SubStr(s2,xPos6,1) = '['

              xPos7  := JSon_get_matching_Delimiter(s2,xPos6+1,'[',']')

              s3     := SubStr(s2,xPos6+1,(xPos7-xPos6)-1)

              xFPos  := xPos7-1

              r := CONVERT_JSON_XML(s3,xNivel+1,xID)

              result := result + r

      EndCase

      s2 := SubStr(s2,xFPos+1,Len(s2)-xFPos)

   else

      EXIT

   EndIf

EndDo

RETURN result

 

De: harbou...@googlegroups.com [mailto:harbou...@googlegroups.com] En nombre de jan.sp...@grecoavalon.com
Enviado el: martes, 18 de mayo de 2021 11:50
Para: harbou...@googlegroups.com
Asunto: RE: [harbour-users] FoxPro to Harbour...

 

Hi everybody:

 

I would like to ask if somebody has already written some JSON-to-XML function?

 

Tx in advance,

 

BR,

Jan Sperling

 

--
--
You received this message because you are subscribed to the Google
Groups "Harbour Users" group.
Unsubscribe: harbour-user...@googlegroups.com
Web: http://groups.google.com/group/harbour-users

---
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to harbour-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/harbour-users/01ac01d74c0e%2445861ff0%24d0925fd0%24%40grecoavalon.com.

Shaji Thomas

unread,
May 20, 2021, 3:22:04 AM5/20/21
to Harbour Users
See the conversation on  this subject  on 04/09/2020 ...

"Hb_JsonEncode() and hb_JsonDecode() are Harbour functions. hb_xmlToHash() and hb_hashToXML() are developed by Przemek and were published in this group many years back." 

jan.sp...@grecoavalon.com

unread,
May 20, 2021, 11:06:52 AM5/20/21
to harbou...@googlegroups.com

Hi Shaji,

Tx for your answer, wasn’t aware of that function…

 

BR,

Jan

Reply all
Reply to author
Forward
0 new messages