xml

Executes an XML function.

Available in:

Apps (win) Apps (char) Reportwriter RPC Standalone PL
X X X X X

Syntax

expr xml(opt[,parm])
int      opt
expr     parm

Description

Performs various XML operations based on the value of opt.
opt parm function
xml_attr attribute name Returns the value of the specified attribute. If the attribute is not found, then it returns NULL.
xml_data N/A Returns the current XML data value as a character string. If an error has occurred in any other XML function, then the error message can be retrieved using xml(xml_data).
xml_endtag N/A Returns true if the XML stream is at the end of a tag.
xml_free N/A Frees all resources associated with the XML system.
xml_init Any valid file source Initializes the XML system using the specified XML stream.
xml_name N/A Returns the current XML tag as a character string.
xml_next N/A Moves to the next XML tag. The entire attribute string is available using xml(xml_data). Returns either the tag code value if xml(xml_tags,list) was called, (-1) if no tags were sent, or NULL if an error occurred. If the return code is NULL, use xml(xml_data) to retrieve the error message.
xml_tags list of tag/value pairs Sends a list of valid XML tags to the XML system in the form of a two column list. The first column is the tag and the second column is its code value.
xml_value N/A Returns the current uninterpreted data from the XML stream. If it returns NULL, then if xml(xml_endtag) returns true, the XML stream is empty; otherwise the XML stream is positioned at a new XML tag.

Examples

/******************************************************************************
** Convert generic XML file to internal list format
**
** parm.0 - XML file
** parm.1 - Internal list file
** 
** Format of list: col0: tag name
**                 col1: attributes (NULL if none)
**                 col2: NULL no data (<..../>)
**                       Char datatype then string data
**                       List datatype then sub-tree
**
*******************************************************************************/

#trigger next_element
/******************************************************************************
** Get next tag element
*******************************************************************************/
{
int rc,end;
rc = xml(xml_next);
if (!rc) error(xml(xml_data));
if (rc < (-1)) end = true;
else end = xml(xml_endtag);
return([xml(xml_name),end,xml(xml_data)]);
}                                          /* next_element                    */

#trigger dive
/******************************************************************************
** Process XML 
*******************************************************************************/
{
int        i;
char       val[500],attr[1000];
local int  end;
local int  level  = parm.0;
local char s[200] = "";
local char tag[100],exit_tag[100] = parm.1;

for (i=level;i;i--) s = s ^^ " ";

while (true) {
  [tag,end,attr] = next_element();

  if (end) {
    if (tag == exit_tag) return;
    list_mod(parm.2,1,tag,attr,NULL);
    continue;
    }

  val = xml(xml_value);
  val = ltrim(rtrim(val,G.sc),G.sc);

  if (xml(xml_endtag) && (tag == xml(xml_name))) {
    list_mod(parm.2,1,tag,attr,val);
    xml(xml_next);                          /* eat                      */
    if (tag == exit_tag) return;    
    }
  else {
    list_mod(parm.2,1,tag,attr,list_open("20 30 20",0));
    dive(level+1,tag,list_curr(parm.2,2));
    if (!exit_tag) return;
    }
  }
}                                           /* dive                           */

#trigger
/******************************************************************************
** Main 
*******************************************************************************/
{
char sc[3] = chr(10,13,32);                 /* trim chars                     */
list LL;

xml(xml_init,parm.0);

LL = list_open("20 30 20",0);

dive(0,NULL,LL);

list_file(LL,parm.1,"x");

xml(xml_free);
}

/****************************************************************************** ** Convert internal XML list to generic XML file ** ** parm.0 - file with list ** ** Format of list: col0: tag name ** col1: attributes (NULL if none) ** col2: NULL no data (<..../>) ** Char datatype then string data ** List datatype then sub-tree ** *******************************************************************************/ #trigger dive /****************************************************************************** ** Process a list *******************************************************************************/ { local int i; local char tag[100]; char s[1000],attr[500]; for (i=list_rows(parm.0);i;i--) { tag = list_curr(parm.0,0); attr = list_curr(parm.0,1); s = "<" ^^ tag; if (attr) s = s ^^ " " ^^ attr; if (list_curr(parm.0,2) == NULL) printf(s ^^ "/>"); else if (datatype(list_curr(parm.0,2)) == "C") printf(s ^^ ">" ^^ translate(translate(translate(translate(translate( list_curr(parm.0,2), "&","&amp;"), "<","&lt;"), ">","&gt;"), "'","&apos;"), """","&quot;") ^^ "</" ^^ tag ^^ ">"); else { /* a sub-list */ printf(s ^^ ">"); dive(list_curr(parm.0,2)); printf("</" ^^ tag ^^ ">"); } /* a sub-list */ list_next(parm.0); } } /* dive */ #trigger /****************************************************************************** ** Main *******************************************************************************/ { list LL; LL = list_open(parm.0,999999); dive(LL); }