XMLTools - Maple Programming Help

Home : Support : Online Help : Connectivity : Web Features : XMLTools : XMLTools/ToRecord

XMLTools

 ToRecord
 format an XML tree as nested records

 Calling Sequence ToRecord(xmlTree, markcdata, decodeentities)

Parameters

 xmlTree - Maple XML tree; XML element markcdata - (optional) truefalse; separate _XML_CDATA decodeentities - (optional) truefalse; decode entities

Description

 • The ToRecord(xmlTree) command formats the XML element xmlTree as nested records instead of nested functions.  Nested records use the name of the entities as members.  The record members are assigned to the entity value, which could be another record.  When the same entity name occurs multiple times at the same level, the values are contained in a list.
 • The special names _order, _value, _XML_CDATA, and _attributes occur in many situations.
 _order is a list of strings that correspond to the member names in the order they occurred in the XML structure.  For example, "123" maps to a record with exports a, b, and _order where a is a list, ["1","2"] and _order is a list, ["a","b","a"].
 _value is the name that is used to hold the unnamed part of an element with mixed substructures.  For example, "12" will have the member a:-_value assigned to "1" in addition to a:-b assigned to "2".
 _XML_CDATA is used as one more level of indirection to indicate CDATA values.  If you use the optional parameter 'markcdata' = false, the CDATA wrapper is removed and it appears as a regular text value.  When converting back to XML string, the _XML_CDATA needs to be put back, or the "" wrapper applied directly to the string.
 _attributes is used to store the attributes of the entity.
 • When 'decodeentities' = true the StringTools:-DecodeEntities command is used to convert each entity to UTF-8 encoding.  Otherwise the entity is inlined as a string of the form "&#...;".  The default is decodeentities = false.
 • A record-based XML structure is especially useful when building and modifying using procedural methods.  Records are mutable data structures so entries can be changed deep inside a recursive program causing the entire tree to be affected by the change.

Examples

 > $\mathrm{with}\left(\mathrm{XMLTools}\right):$

This example shows how repeated elements are put into a list, and the order they occurred can be deduced from the _order export.

 > $\mathrm{xml}≔\mathrm{ParseString}\left("123"\right):$
 > $r≔\mathrm{ToRecord}\left(\mathrm{xml}\right):$
 > $\mathrm{Print}\left(r\right)$
     1     2     3
 > $r:-\mathrm{doc}:-a\left[1\right]$
 ${"1"}$ (1)
 > $r:-\mathrm{doc}:-b$
 ${"2"}$ (2)
 > $r:-\mathrm{doc}:-a\left[2\right]$
 ${"3"}$ (3)
 > $r:-\mathrm{doc}:-\mathrm{_order}$
 $\left[{"a"}{,}{"b"}{,}{"a"}\right]$ (4)

This example shows an instance where the _value export is introduced.

 > $r≔\mathrm{ToRecord}\left(\mathrm{ParseString}\left("12"\right)\right):$
 > $\left[\mathrm{exports}\left(r:-\mathrm{doc}\right)\right]$
 $\left[{a}{,}{\mathrm{_value}}{,}{\mathrm{_order}}\right]$ (5)
 > $r:-\mathrm{doc}:-\mathrm{_value}$
 ${"2"}$ (6)

This example also highlights the _value export, and also shows how eval() is needed to look at members that are assigned to a record.

 > $r≔\mathrm{ToRecord}\left(\mathrm{ParseString}\left("12"\right)\right):$
 > $\mathrm{eval}\left(r:-a\right)$
 ${\mathrm{Record}}{}\left({\mathrm{_value}}{=}{"1"}{,}{b}{=}{"2"}{,}{\mathrm{_order}}{=}\left[{"_value"}{,}{"b"}\right]\right)$ (7)
 > $r:-a:-\mathrm{_value}$
 ${"1"}$ (8)
 > $r:-a:-b$
 ${"2"}$ (9)

This example shows a structure containing CDATA.

 > $r≔\mathrm{ToRecord}\left(\mathrm{ParseString}\left(""\right)\right):$
 > $\mathrm{eval}\left(r:-a\right)$
 ${\mathrm{Record}}{}\left({\mathrm{_XML_CDATA}}{=}{"the data"}{,}{\mathrm{_order}}{=}\left[{"_XML_CDATA"}\right]\right)$ (10)
 > $r:-a:-\mathrm{_XML_CDATA}$
 ${"the data"}$ (11)
 > $r≔\mathrm{ToRecord}\left(\mathrm{ParseString}\left(""\right),'\mathrm{markcdata}'=\mathrm{false}\right):$
 > $\mathrm{eval}\left(r:-a\right)$
 ${"the data"}$ (12)

This example shows a structure containing attributes.

 > $r≔\mathrm{ToRecord}\left(\mathrm{ParseString}\left(""\right)\right):$
 > $\mathrm{eval}\left(r:-a:-\mathrm{_attributes}\right)$
 ${\mathrm{Record}}{}\left({\mathrm{color}}{=}{"red"}{,}{\mathrm{size}}{=}{"10"}\right)$ (13)
 > $r:-a:-\mathrm{_attributes}:-\mathrm{color}$
 ${"red"}$ (14)
 > $r:-a:-\mathrm{_attributes}:-\mathrm{size}$
 ${"10"}$ (15)

This example shows a procedure that walks the entries in order

 > disp := proc( val, lev := 0 )    local count, i, namei, elemi, v;    if val::list then        seq( procname(i,lev+1), i=val );    elif val::record and member(_order,val) then        count := table(sparse);        for i from 1 to numelems(val:-_order) do            namei := val:-_order[i];            printf("%*s%s:\n",2*lev,"",namei);            elemi := val[convert(namei,name)];            count[namei] := count[namei]+1;            v := if(elemi::list,elemi[count[namei]],elemi);            if namei = "_value" and v::string then                printf("%*s%s\n",2*(lev+1),"",v);            elif namei = "_order" then                #skip            elif namei = "_XML_CDATA" and v::string then                printf("%*s\n",2*(lev+1),"",v);            else                procname(v,lev+1);            fi;        od;    else        printf("%*s%a\n",2*lev,"",eval(val));    fi; end:
 > $r≔\mathrm{ToRecord}\left(\mathrm{ParseString}\left("12183"\right)\right)$
 ${r}{≔}{\mathrm{Record}}{}\left({\mathrm{doc}}{=}{\mathrm{Record}}{}\left({\mathrm{...}}\right){,}{\mathrm{_order}}{=}\left[{"doc"}\right]\right)$ (16)
 > $\mathrm{disp}\left(r\right)$
 doc:   a:     "1"   b:     "2"   c:     _value:       18     _value:       data   a:     "3"   _attributes:     Record('id' = "17")

Compatibility

 • The XMLTools[ToRecord] command was introduced in Maple 2018.