| (!******************************************************
   Mosel Example Problems
   ======================
   file xparse.mos
   ```````````````
   A simple example of the use of the SAX parser in mmxml
   
   (c) 2014 Fair Isaac Corporation
       author: Y. Colombani, October 2014
*******************************************************!)
model xparse
uses 'mmxml'
declarations
 d:xmldoc
end-declarations
forward public procedure myload(d:xmldoc,fname:text)
myload(d,"refexample.xml")
save(d,"")
!------------------------------------------------------
! The following structure will be used to store the state of the parser
declarations
 public s_ctx=
    record
	doc:xmldoc
	curnode:integer
    end-record
end-declarations
!------------------------------------------------------
! **** Callback function: Beginning of an element ****
public function start_elt(c:s_ctx,name:text,nba:integer):integer
 declarations
  att,val:text
 end-declarations
 c.curnode:=addnode(c.doc,c.curnode,XML_ELT,name)
 ! 'xmlattr' is used to retrieve attributes associated to current node
 ! 'xmlattr(att,val)' can also be used to retrieve the value of attribute 'att'
 forall(i in 1..nba) do
  xmlattr(i,att,val)
  setattr(c.doc,c.curnode,string(att),val)
 end-do
 xmlattr("name",val)
end-function
! **** Callback function: Mark the end of a an element ****
public function end_elt(c:s_ctx):integer
 c.curnode:=getparent(c.doc,c.curnode)
end-function
! **** Callback function: Store a text object 
!     'type' indicates the XML node type (e.g. TEXT, CDATA...) ****
public function txthdl(c:s_ctx,type:integer,data:text):integer
 n:=addnode(c.doc,c.curnode,type,data)
end-function
! **** Callback function: Record document declaration details ****
public function xdecl(c:s_ctx,vers:text,encoding:text,std:integer):integer
 setencoding(c.doc,string(encoding))
 setstandalone(c.doc,std)
 setxmlversion(c.doc,string(vers))
end-function
! **** Callback function: Store a processing instruction ****
public function pinst(c:s_ctx,target:text,data:text):integer
 n:=addnode(c.doc,c.curnode,XML_PINST,string(target),data)
end-function
!------------------------------------------------------
! **** An implementation of 'load(xmldoc,text)' using the SAX parser ****
public procedure myload(d:xmldoc,fname:text)
 declarations
  afct:array(range) of string
  ctx:s_ctx
 end-declarations
 afct(XML_FCT_DECL):="xdecl"         ! Declaration (XML version, encoding)
 afct(XML_FCT_TXT):="txthdl"         ! Text
 afct(XML_FCT_CDATA):="txthdl"       ! Cdata
 afct(XML_FCT_COM):="txthdl"         ! Comment
 afct(XML_FCT_DATA):="txthdl"        ! Data (non qualifiee)
 afct(XML_FCT_PINST):="pinst"        ! Processing instruction
 afct(XML_FCT_OPEN_ELT):="start_elt" ! Start of an element
 afct(XML_FCT_CLOSE_ELT):="end_elt"  ! End of an element
 ctx.curnode:=0;
 fopen(fname,F_INPUT)
 ! 'xmlparse' expects a table of functions (all are optional)
 ! the option indicates whether spaces should be kept (0: keep spaces;
 ! 1: skip spaces)
 ! the last argument will be passed to all functions
 rts:=xmlparse(afct,1,ctx)
 fclose(F_INPUT)
 d:=ctx.doc
end-procedure
end-model
 | 
| (!******************************************************
   Mosel Example Problems
   ======================
   file xparse.mos
   ```````````````
   A simple example of the use of the JSON parser in mmxml
   
   (c) 2014 Fair Isaac Corporation
       author: Y. Colombani, October 2014
*******************************************************!)
model jparse
uses 'mmxml'
declarations
 d:xmldoc
 public src=`
[
 {
  "name": "bob",
  "age": 25,
  "student": true,
  "phone":
  [
   { "type": "home", "number": "1234567900" },
   { "type": "work", "number": "6789012345" }
  ],
  "empty":null
  }
]
`
end-declarations
forward public procedure myjsonload(d:xmldoc,fname:text)
myjsonload(d,"text:src")
save(d,"")
!------------------------------------------------------
! The following structure will be used to store the state of the parser
declarations
 public s_ctx=
    record
	doc:xmldoc
	jtype:array(0..3) of string
	curnode:integer
    end-record
end-declarations
!------------------------------------------------------
! **** Callback function: Start an object ****
public function open_obj(c:s_ctx,name:text):integer
 c.curnode:=addnode(c.doc,c.curnode,XML_ELT,if(name="","jsv",string(name)))
 setattr(c.doc,c.curnode,"jst","obj")
end-function
! **** Callback function: End an object ****
public function close_obj(c:s_ctx):integer
 c.curnode:=getparent(c.doc,c.curnode)
end-function
! **** Callback function: Start an array ****
public function open_arr(c:s_ctx,name:text):integer
 c.curnode:=addnode(c.doc,c.curnode,XML_ELT,if(name="","jsv",string(name)))
 setattr(c.doc,c.curnode,"jst","arr")
end-function
! **** Callback function: End an array ****
public function close_arr(c:s_ctx):integer
 c.curnode:=getparent(c.doc,c.curnode)
end-function
! **** Callback function: Store a value ****
public function setvalue_all(c:s_ctx,name:text,type:integer,val:text):integer
 n:=addnode(c.doc,c.curnode,XML_ELT,if(name="","jsv",string(name)),val)
 setattr(c.doc,n,"jst",c.jtype(type))
end-function
! **** Callback function: Store a numerical value 
!      ('JSON_FCT_TEXT' is used if this one is not defined) ****
public function setvalue_num(c:s_ctx,name:text,val:real):integer
 n:=addnode(c.doc,c.curnode,XML_ELT,if(name="","jsv",string(name)),text(val))
 setattr(c.doc,n,"jst","num")
end-function
! **** Callback function: Store a Boolean value 
!      ('JSON_FCT_TEXT' is used if this one is not defined) ****
public function setvalue_bool(c:s_ctx,name:text,val:boolean):integer
 n:=addnode(c.doc,c.curnode,XML_ELT,if(name="","jsv",string(name)),text(val))
 setattr(c.doc,n,"jst","boo")
end-function
! **** Callback function: Store the null value 
!      ('JSON_FCT_TEXT' is used if this one is not defined) ****
public function setvalue_null(c:s_ctx,name:text):integer
 n:=addnode(c.doc,c.curnode,XML_ELT,if(name="","jsv",string(name)),"null")
 setattr(c.doc,n,"jst","nul")
end-function
!------------------------------------------------------
! **** An implementation of 'jsonload(xmldoc,text)' using the JSON parser ****
public procedure myjsonload(d:xmldoc,fname:text)
 declarations
  afct:array(range) of string
  ctx:s_ctx
 end-declarations
 afct(JSON_FCT_OPEN_OBJ):="open_obj"      ! Start an object
 afct(JSON_FCT_CLOSE_OBJ):="close_obj"    ! End an object
 afct(JSON_FCT_OPEN_ARR):="open_arr"      ! Start an array
 afct(JSON_FCT_CLOSE_ARR):="close_arr"    ! End an array
 afct(JSON_FCT_TEXT):="setvalue_all"      ! A value as a text
 afct(JSON_FCT_NUM):="setvalue_num"       ! A numerical value
 afct(JSON_FCT_BOOL):="setvalue_bool"     ! A Boolean value
 afct(JSON_FCT_NULL):="setvalue_null"     ! The "null" value
 fopen(fname,F_INPUT)
 ctx.curnode:=0;
 ctx.jtype::([0,1,2,3])["nul","str","num","boo"]
 ! 'jsonparse' expects a table of functions (all are optional)
 ! the last argument will be passed to all functions
 rts:=jsonparse(afct,ctx)
 fclose(F_INPUT)
 d:=ctx.doc
end-procedure
end-model
 |