Monday, November 08, 2010 at 12:06 AM.
system.verbs.builtins.table.xmlToTable
on xmlToTable (xmltext, adrtable=nil) {
<<Changes:
<<1/31/03; 3:40:12 PM by JES
<<Decode "alpha" entities in attribute values in the correct order.
<<6/29/01; 3:13:54 PM by JES
<<Fixed various problems with entity-decoding.
<<6/28/01; 10:28:58 PM by JES
<<Convert the XML representation of a table, into a Frontier table as specified here:
<<http://smurfturf.manilasites.com/stories/storyReader$214
<<s is the XML text
<<adrtable is the address of the location to create the table.
<<If nil, the table will be created at the address specified by the address attribute of the top-level <table> element.
local (xstruct);
xml.compile (xmltext, @xstruct);
local (adrtablestruct = xml.getAddress (@xstruct, "table"));
on getAttributeValue (adrelement, attname) {
local (adratts = @adrelement^.["/atts"]);
local (adratt = @adratts^.[attname]);
local (value = xml.entityDecode (adratt^, false, true));
value = string.replaceall (value, "<", "<");
value = string.replaceall (value, ">", ">");
value = string.replaceall (value, """, "\"");
value = string.replaceAll (value, "'", "\'");
value = string.replaceall (value, "&", "&");
return (value)};
if adrtable == nil { //get the address from the top-level <table> element
try {
adrtable = address (getAttributeValue (adrtablestruct, "address"))}
else {
scriptError ("Can't convert to a table because no destination address was specified.")}};
on doListOrRecord (adrlist, adrdest, flrecord=false) {
adrdest^ = {};
local (adritem);
for adritem in adrlist {
if nameOf (adritem^) beginsWith "/" {
continue};
local (item); new (tableType, @item);
if flrecord {
local (name = getAttributeValue (adritem, "name"));
main (adritem, @item, name);
adrdest^ = adrdest^ + {name:item[1]}}
else { //list
main (adritem, @item, "item");
adrdest^ = adrdest^ + item.item}};
return (true)};
on doOutline (adroutline, adrdest, flscript=false) {
local (adropml);
for adropml in adroutline {
if xml.convertToDisplayName (nameOf (adropml^)) == "opml" {
break}};
local (xtext = xml.decompile (adropml));
if flscript {
local (s);
op.xmlToOutline (xtext, @s);
new (scriptType, adrdest);
local (oldtarget = target.set (adrdest));
op.insertOutline (@s, down);
op.firstSummit ();
op.deleteLine ();
target.set (oldtarget)}
else { //outline
op.xmlToOutline (xtext, adrdest)};
return (true)};
on doMenubar (adrmenu, adrdest) {
new (menubarType, adrdest);
on addHeading (s, flfirstheading) {
if flfirstheading {
op.setLineText (s)}
else {
op.insert (s, down)};
return (true)};
on doLevel (adr) {
local (adritem, flfirstheading = true);
for adritem in adr {
if nameOf (adritem^) beginsWith "/" {
continue};
local (itemtype = xml.convertToDisplayName (nameOf (adritem^)));
case itemtype {
"script" {
local (name = getAttributeValue (adritem, "name"));
addHeading (name, flfirstheading);
local (commandKey);
if defined (adritem^.["/atts"].commandKey) {
commandKey = char (number (adritem^.["/atts"].commandKey))};
if commandKey != nil {
menu.setCommandKey (commandKey)};
local (s);
doOutline (adritem, @s, true);
menu.setScript (@s)};
"menubar" {
local (name = getAttributeValue (adritem, "name"));
addHeading (name, flfirstheading);
op.insert ("", right);
doLevel (adritem);
op.go (left, 1)};
"separator" {
addHeading ("-", flfirstheading)}};
flfirstheading = false}};
local (oldtarget = target.set (adrdest));
doLevel (adrmenu);
target.set (oldtarget);
return (true)};
on doTable (adrtable, adrdest) {
local (adritem);
new (tableType, adrdest);
for adritem in adrtable {
if nameOf (adritem^) == "/atts" {
continue};
if nameOf (adritem^) == "/pcdata" {
continue};
local (name = getAttributeValue (adritem, "name"));
main (adritem, adrdest, name)};
return (true)};
on main (adritem, adrdest, name) {
local (typestring = xml.convertToDisplayName (nameOf (adritem^)));
local (adritemdest = @adrdest^.[name]);
case typestring {
"table" {
doTable (adritem, adritemdest)};
"outline" {
doOutline (adritem, adritemdest)};
"script" {
doOutline (adritem, adritemdest, true)};
"wptext" {
local (ix = 1; adrbody);
loop { //find <body>
if string.nthField (nameOf (adritem^[ix]), '\t', 2) == "body" {
adrbody = @adritem^[ix];
break};
ix++};
local (value);
if typeOf (adrbody^) == tableType {
value = xml.entityDecode (adrbody^.["/pcdata"], true)}
else {
value = xml.entityDecode (adrbody^, true)};
wp.newTextObject (value, adritemdest)};
"list" {
doListOrRecord (adritem, adritemdest)};
"record" {
doListOrRecord (adritem, adritemdest, true)};
"binary" {
local (value = base64.decode (adritem^.["/pcdata"]));
adritemdest^ = binary (value);
setBinaryType (adritemdest, getAttributeValue (adritem, "type"))};
"menubar" {
doMenubar (adritem, adritemdest)}}
else { //scalar
local (value = getAttributeValue (adritem, "value"));
adritemdest^ = [typestring] (value)};
return (true)};
doTable (adrtablestruct, adrtable);
return (true)}
<<bundle //testing
<<table.xmlToTable ("<table name=\"myTable\" address=\"workspace.myTable\"><string name=\"myString\" value=\"This is a string.\"/></table>")
<<table.xmlToTable (string (workspace.foo), @workspace.deserializedTable)
This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.