System Functions
XML( ) XML Parsing/Generation Facility
  The XML function is a +PxPlus Exclusive
Format
Append a value: XML(ADD strval$ TO curxml$ , KEY= tagname$ [ , OPT= propstr$ ] [,ERR=stmtref ] )
Get next value: XML(NEXT FROM curxml$ , IND= offsetvar , KEY= tagvar$ [ , OPT= propvar$ ] [,ERR=stmtref ] )
Append a property: XML( PROPERTY ADD strval$ TO curprop$ , KEY= propname$ [,ERR=stmtref ] )
Get next property: XML(PROPERTY NEXT FROM curprop$ , IND= offsetvar , KEY= propvar$ [,ERR=stmtref ] )

Where:

curprop$ The XML property string that is currently being processed. When used in an ADD this is the string that will be appended to. In the NEXT FROM, this is the string that is being parsed.
curxml$ The XML statement that is currently being processed. When used in an ADD this is the XML that will be appended to. In the NEXT FROM, this is the XML that is being parsed.
offsetvar The numeric variable that is used to track the offset into curxml$ or curprop$ during the parsing. It is the one (1) based offset into the string. A value of zero is considered as an offset of one. It will be updated after the execution of the function with the offset where processing is to continue.
propname$ String value or expression containing the property name to add. This value must not be null.
propstr$ String value or expression containing the properties associated with the tag being added.
propvar$ The string variable that will receive the property name.
strval$ String value or expression containing the value to be added.
tagname$ String value or expression containing the name of the tag to add. If this value is a null string, no tag will be inserted.
tagvar$ The string variable that will receive the tag name.
stmtref Program line number or statement label where the program will transfer to in case of an error.
   
Returns The ADD form of the function returns the new XML or Property string after the value has been appended. The NEXT FROM form returns the next value from the parsed value.
   
Description The XML() function is designed to assist application programs parse and construct XML documents. The ADD functions allow for the easy construction of XML data assuring the proper placement and matching of names/tags within the data.

The NEXT FROM provides the ability to parse an XML string, retrieving the data values for each corresponding tag in accordance with XML specifications. The NEXT FROM automatically matches each start and end tag or empty tags as well as provides detection of comments, DID and PI type XML records.

To construct a XML string, the XML ADD function is called with each of its corresponding data elements. Generally, an XML document will be made up of multiple elements in some form of hierarchy which is accomplished by simply adding XML elements themselves to an existing XML string.

   
Examples The following example shows how a simple multi-level XML can be created -- in this case, an XML document describing two organizations:

First we need to construct a XML list of employees

->empl$=XML(add "John" to "",key="Employee")
->?empl$
<Employee>John</Employee>

The ADD logic created the XML starting with a NULL string for the first employee. Now, we will add the other employees.

->empl$=XML(add "Fran" to empl$,key="Employee")
->?empl$
<Employee>John</Employee>
<Employee>Fran</Employee>

Notice that we passed the pre-existing XML text which contained "John" to the ADD. This resulted in XML with both entries.

->empl$=XML(add "Sammy" to empl$,key="Employee",opt="role='Sales' ")
->?empl$
<Employee>John</Employee>
<Employee>Fran</Employee>
<Employee role='Sales'>Sammy</Employee>

Okay, now we have the list of company employees so we can create a company XML. But for this the company needs a property of its name.

->comp_prop$=XML(property add "Widgets Plus" to "", key="name")
->?comp_props$
name='Widgets Plus'

Now we will create the company XML entry:

->company$=XML(add empl$ to "",key="company",opt=comp_prop$)
->?company$
<company name='Widgets Plus'>
  <Employee>John</Employee>
  <Employee>Fran</Employee>
  <Employee role='Sales'>Sammy</Employee>
</company>

So there we have a XML description of a company. So let's extend this to create a data set of multiple companies and call it 'suppliers'. First, we need another company.

->empl$=XML(add "Jane" to "",key="Employee",opt="role='Owner' " )
->empl$=XML(add "Roberto" to empl$,key="Employee")
->empl$=XML(add "Fredrico" to empl$,key="Employee",opt="role='Sales' ")
->comp2_prop$=XML(property add "More Gadgets" to "", key="name")
->company$=XML(add empl$ to company$,key="company",opt=comp_prop$)
->?company$
<company name='Widgets Plus'>
  <Employee>John</Employee>
  <Employee>Fran</Employee>
  <Employee role='Sales'>Sammy</Employee>
</company>
<company name='More Gadgets'>
  <Employee role='Owner'>Jane</Employee>
  <Employee>Roberto</Employee>
  <Employee role='Sale'>Fredrico</Employee>
</company>

In the above example, we added the second company set to the first. We could instead have created a new XML data set for the second company and merged them together into companies$ as follows:

->comp2$=XML(add empl$ to ""$,key="company",opt=comp_prop$)
->companies$=XML(add company$ to "",key="")
->companies$=XML(add comp2$ to companies$,key="")
->companies$
<company name='Widgets Plus'>
  <Employee>John</Employee>
  <Employee>Fran</Employee>
  <Employee role='Sales'>Sammy</Employee>
</company>
<company name='More Gadgets'>
  <Employee role='Owner'>Jane</Employee>
  <Employee>Roberto</Employee>
  <Employee role='Sale'>Fredrico</Employee>
</company>

Finally, we can create our supplier list:

->suppliers$=XML(add company$ to "",key="suppliers")
->suppliers$
<suppliers>
  <company name='Widgets Plus'>
    <Employee>John</Employee>
    <Employee>Fran</Employee>
    <Employee role='Sales'>Sammy</Employee>
  </company>
  <company name='More Gadgets'>
    <Employee role='Owner'>Jane</Employee>
    <Employee>Roberto</Employee>
    <Employee role='Sale'>Fredrico</Employee>
  </company>
</suppliers>

Now to parse the value in suppliers$ lets use a simple program:

0010 LET VALU$=SUPPLIERS$
0020 GOSUB PARSER
0030 STOP
0040 PARSER:
0050 LOCAL OFST
0060 LOCAL XML$
0070 LET XML$=VALU$
0080 WHILE 1
0090 LET VALU$=XML(NEXT FROM XML$,IND=OFST,KEY=NAME$,OPT=PROP$,ERR=*BREAK)
0100 IF NAME$="" THEN PRINT " ",VALU$ ELSE PRINT "Tag:",NAME$,@(20),PROP$; GOSUB PARSER
0110 WEND
0120 RETURN

If we run this program, we get:

Tag:suppliers
Tag:company         name='Widgets Plus'
Tag:Employee
    John
Tag:Employee
    Fran
Tag:Employee        role='Sales'
    Sammy
Tag:company         name='Widgets Plus'
Tag:Employee        role='Owner'
    Jane
Tag:Employee
    Roberto
Tag:Employee        role='Sales'
    Fredrico



* Note * Normally, proper XML will have a PI header indicating that the document is XML and what data format/spec is being used thus, if we wanted to actually send the value in suppliers to another application, we would normally have done something like:

->xml$=XML(add "" to "",key="?xml",opt="version='1.0' ")
->xml$=XML(add company$ to xml$,key="suppliers")