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_esc string Returns a string with string's special HTML characters converted to HTML entities (see xml_unesc).
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_unesc string Returns a string with string's HTML entities converted to special HTML characters (see xml_esc).
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 a generic XML file to internal list format:
/******************************************************************************
** 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 an internal XML list to a generic XML file.
/******************************************************************************
** 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);
}
Convert special HTML characters to HTML entities and back again:
{
char buf[100];
buf = xml(xml_esc,"<data wb='www.trifox.com?cow=42&moo=53'>");
printf(buf);
buf = xml(xml_unesc,buf);
printf(buf);
}
returns
&lt;data wb=&apos;www.trifox.com?cow=42&amp;moo=53&apos;&gt;
<data wb='www.trifox.com?cow=42&moo=53'>