KNOWLEDGE BASE
Log In    |    Knowledge Base    |    4D Home
Tech Tip: Importing XML Structure Definition Programatically
PRODUCT: 4D | VERSION: 14 R5 | PLATFORM: Mac & Win
Published On: August 4, 2016

4Dv14R4 introduced a new command that allows a structure definition to be imported programatically from an xml definition generated by the either the export wizard or the new EXPORT STRUCTURE command also introduced.

The EXPORT STRUCTURE command populates a text variable with the structure definition and can be saved externally with the TEXT TO DOCUMENT command.

To import the structure programatically, populate a text variable with the xml definition of the structure and pass it to the new IMPORT STRUCTURE command. There are many cases that can cause errors listed below:

  • Formatted Incorrectly
  • Structure is in Compiled and/or read only mode
  • Table has same name as a local one
The errors are self explanitory when triggered, however it may not be as obvious which table already exists for the third error without taking a look at both the structure and the xml.

Below is an error method that will list the conflicting tables which can be useful for large database structures with numerous tables:

//Err_IMPORT_STUCTURE_List_Tables
//
// Desription:
// ON ERR CALL method to be used with the IMPORT STRUCTURE command
// to return the list of table names that already exist in an Alert
//
// Parameters:
// xmlDefinition_t: Text process variable containing xmlDefinition
//
// Results:
// Alert Message with list of tables that already exist
// ----------------------------------------------------

ARRAY LONGINT($errCodes_al;0)
ARRAY TEXT($code_at;0)
ARRAY TEXT($errDesc_at;0)
GET LAST ERROR STACK($errCodes_al;$code_at;$errDesc_at)

If ($errCodes_al{1}=1227)
   ARRAY TEXT($structTables_at;0)
   ARRAY TEXT($tableNames_at;0)
   C_LONGINT($last_l)
   C_LONGINT($count_l)
   C_LONGINT($size_l)
   C_TEXT($xmlRef_t)
   C_TEXT($tableName_t)
   C_TEXT($msg_t)
   ARRAY TEXT($xmlChildRef_at;0)

   $last_l:=Get last table number

   For ($count_l;1;$last_l)
      If (Is table number valid($count_l)=True)
         APPEND TO ARRAY($structTables_at;Table name($count_l))
      End if
   End for

   $xmlRef_t:=DOM Parse XML variable(xmlDefinition_t)

   DOM Find XML element($xmlRef_t;"/base/table";$xmlChildRef_at)
   $size_l:=Size of array($xmlChildRef_at)
   If($size_l>0)
      For($count_l;1;$size_l)
         DOM GET XML ATTRIBUTE BY NAME($xmlChildRef_at{$count_l);"name";$tableName_t)
         If (Find in array($structTables_at;$tablename_t)>0)
            APPEND TO ARRAY($tableNames_at;$tableName_t)
         End if
      End for

      $size_l:=Size of array($tableNames_at)
      If ($size_l>0)
         $msg_t:="ERROR! The following Tables already exist:"
         For($count_l;1;$size_l)
            $msg_t:=$msg_t+"\n "+$tableNames_at{$count_l}
         End for
         Alert($msg_t)
      End if
   End if
   DOM CLOSE XML($xmlRef_t)
End if


Example of using the method:
$location_t:=Get 4D folder(Current resources folder)+"4DStructDef.xml"
xmlDefinition_t:=Document to text($location_t)
ON ERR CALL("Err_IMPORT_STUCTURE_List_Tables")
IMPORT STRUCTURE(xmlDefinition_t)
ON ERR CALL("")