Available in:
Apps (win)
Apps (char)
Reportwriter
RPC
Standalone PL
X
X
X
X
X
expr xml(opt[,parm]) int opt expr parm
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. |
/****************************************************************************** ** 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), "&","&"), "<","<"), ">",">"), "'","'"), """",""") ^^ "</" ^^ 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
<data wb='www.trifox.com?cow=42&moo=53'> <data wb='www.trifox.com?cow=42&moo=53'>