Marshalling Arrays

David Bovill david at openpartnership.net
Tue Dec 6 10:18:40 EST 2005


Thought I'd post these scripts as they are related to the questions  
Xavier raised regarding using arrays and nesting... but first some  
comments and questions:

      1) Marshalling menas packing some data into some format for  
sedning somewhere and then unpacking it at the other end.

     2) getprop and setprop handlers cannot unfortunately use arrays  
- so you need to use marshalling to get around this.

     3) Web services often use XML to do this marshalling

     4) XML is a little heavy and complicated (see the difference in  
the two array marshalling scripts)

     5) For some reason base64Encode can include some sort of return  
character (docs say this is not the case) - so breaks with "<"  
characters - urlEncoding seems to work.


--> Arrays and XML
-
function array_ToBaseTable someArray
     put keys(someArray) into someKeys
     put empty into baseTable
     repeat for each line someKey in someKeys
         put someArray[someKey] into someValue
         put urlEncode(someValue) into encodedData
         -- put base64Encode(someValue) into encodedData
         -- replace return with empty in encodedData
         put someKey & tab & encodedData & return after baseTable
     end repeat
     delete last char of baseTable
     return baseTable
end array_ToBaseTable

function array_FromBaseTable baseTable
     set the itemDelimiter to tab
     repeat for each line someLine in baseTable
         put item 1 of someLine into someKey
         put item 2 of someLine into encodedData
         put urlDecode(encodedData) into someValue
         -- put base64Decode(encodedData) into someValue
         put someValue into someArray[someKey]
     end repeat
     return someArray
end array_FromBaseTable

function array_ToXml someArray, baseXML, extraXML, parentAddNode
   -- array must have XML-safe key names
   -- put array_SafeKeys(someArray) into someArray

   if char 1 of baseXML is not "<" then
     put baseXML into tagName
     put "<" & tagName & "></" & tagName & ">" into baseXML
   end if

   put revCreateXMLTree(baseXML,true,true,false) into treeID

   if treeID is not a number then
     return treeID
   else
     set the itemDelimiter to ";"

     put keys(someArray) into arrayKeys
     put empty into someXml
     repeat for each line vCalNodeName in arrayKeys
       put someArray[vCalNodeName] into nodeContents

       put item 1 of vCalNodeName into nodeName
       delete item 1 of vCalNodeName

       revAddXMLNode treeID, empty, nodeName, nodeContents
       put the result into addedNode

       repeat for each item attributePair in vCalNodeName
         set the itemDelimiter to "="
         put item 1 of attributePair into attributeName
         put item 2 of attributePair into attributeValue

         -- may not be fully XML compliant!
         replace quote with empty in attributeValue
         set the itemDelimiter to ";"

         revSetXMLAttribute treeID, addedNode, attributeName,  
attributeValue
       end repeat
     end repeat

     if extraXML is not empty then
       revAppendXML treeID, parentAddNode, extraXML
     end if

     put revXMLText(treeID) into someXML
     revDeleteXMLTree treeID
     return someXml
   end if
end array_ToXml

function xml_ToArray someXML
     -- only for simple XML (with one level)
     put revCreateXMLTree(someXML,true,true,false) into treeID
     if treeID is not a number then
         return treeID
     else
         put revXMLRootNode(treeID) into rootNode
         put revXMLChildNames(treeID , rootNode, return, empty,  
false) into arrayKeys
         put revXMLFirstChild(treeID, rootNode) into thisNode

         put empty into nodeArray
         put revXMLNumberOfChildren(treeID, rootNode, empty, 0) into  
numOfFirstChildren
         set the itemDelimiter to "/"
         repeat (numOfFirstChildren - 0)
             put revXMLNodeContents(treeID, thisNode) into nodeContents
             put last item of thisNode into nodeName

             put nodeContents into nodeArray[nodeName]

             put revXMLNextSibling(treeID, thisNode) into nextNode
             put nextNode into thisNode
         end repeat

         revDeleteXMLTree treeID
         return nodeArray
     end if
end xml_ToArray




More information about the use-livecode mailing list