interplay | mam swodl reference - avid...

134
Interplay ® | MAM SWoDL Reference Release 5

Upload: others

Post on 09-Feb-2021

2 views

Category:

Documents


0 download

TRANSCRIPT

  • Interplay® | MAM SWoDL Reference

    Release 5

  • Contents Using This Reference ....................................................................... 5

    Symbols and Conventions .......................................................................................... 5 If You Need Help ......................................................................................................... 6 Avid Training Services ................................................................................................ 6

    1 Introduction ....................................................................................... 7

    2 Basic Language Elements ................................................................ 8 Command Separator, Identifiers ................................................................................. 8 Comments ................................................................................................................... 9 Status Definitions ........................................................................................................ 9 Literals ....................................................................................................................... 10

    String Literals ....................................................................................................... 10 Integer Literals ..................................................................................................... 11 Floating-Point Literals .......................................................................................... 11 Boolean Literals ................................................................................................... 11

    Variables and Constants ........................................................................................... 12 Variable Declaration ............................................................................................. 13 Assigning a Value to a Variable ........................................................................... 14 Constants ............................................................................................................. 15 System Variables ................................................................................................. 15

    Structs and Arrays ..................................................................................................... 18 Structs .................................................................................................................. 18 Arrays ................................................................................................................... 20 Combining Structs and Arrays ............................................................................. 22 Using Arrays and Structs to Parse XML Documents ........................................... 24

    Expressions ............................................................................................................... 27 Operators ............................................................................................................. 27 Type Considerations ............................................................................................ 28 Cast Operators ..................................................................................................... 29 Pitfall: Variables May Change Operation Type .................................................... 29

    Command Blocks ...................................................................................................... 30 Labels, Goto, Gosub, and Return ............................................................................. 31

    Labels and Goto ................................................................................................... 31 Gosub and Return ................................................................................................ 31

    Exit ............................................................................................................................ 32 Error .......................................................................................................................... 32 Delay ......................................................................................................................... 32 Suspend .................................................................................................................... 32 Try-catch, Throw, and Assert .................................................................................... 33 Conditional Command: If – Then – Else ................................................................... 34 Loops ......................................................................................................................... 34

  • 3

    While Loop ........................................................................................................... 35 Do-while Loop ...................................................................................................... 35 Retry-while Loop .................................................................................................. 35

    3 Built-in Functions ............................................................................ 37 String Handling .......................................................................................................... 37

    String Comparison: compare ............................................................................... 38 Extracting Part of a String: substr ........................................................................ 38 Length of a String: length ..................................................................................... 39 Find a Substring in a String: find .......................................................................... 39 Find Last Occurrence of a Substring: findreverse ............................................... 39 Trim a String: trim................................................................................................. 40 Replace Substrings: replace ................................................................................ 40

    XML Functions .......................................................................................................... 40 XML Encoding and Decoding: xmlencode and xmldecode ................................. 41 Parsing XML documents ...................................................................................... 42 Creating XML documents .................................................................................... 53

    Array Functions ......................................................................................................... 59 Aggregating elements: array_aggregate ............................................................. 59 Checking a condition on all elements: array_all .................................................. 60 Checking if any element fulfills a condition: array_any ........................................ 61 Transforming an array: array_select .................................................................... 62 Filtering elements with a condition: array_where ................................................. 63

    JSON Functions ........................................................................................................ 64 Parsing JSON Fragments .................................................................................... 64 Creating JSON Fragments ................................................................................... 65

    Regular Expressions ................................................................................................. 66 Regular Expression Match: regex_ismatch ......................................................... 66 Finding Regular Expression Matches: regex_find ............................................... 67 Replacing Using Regular Expressions: regex_replace ....................................... 67 Defining Match Options ........................................................................................ 69

    Configuration Settings ............................................................................................... 69 Common References ................................................................................................ 70 Handling Lists: getelement, getnumberofelements ................................................... 72 Random Number Generation .................................................................................... 73 Floating-Point Functions ........................................................................................... 73 Empty Operation: nop ............................................................................................... 74

    4 HTTP POST Web Methods .............................................................. 75 Declaration of HTTP POST Methods ........................................................................ 75

    Declaration of Input Parameters .......................................................................... 77 Declaration of Return Parameter ......................................................................... 77 Renaming HTTP POST Methods ......................................................................... 81 Declaration Modifier const ................................................................................... 82 Defining the Target in the Declaration of a Method ............................................. 82

  • 4

    Calling HTTP POST Methods ................................................................................... 83 Methods without Return Parameters ................................................................... 83 Methods with Return Parameters ........................................................................ 84 Using an Explicit URL .......................................................................................... 85 Lists as Parameters of an HTTP POST Method .................................................. 85

    5 SOAP Web Methods ........................................................................ 86 Declare and Call SOAP Methods .............................................................................. 86

    Method Name and Input Parameters ................................................................... 87 Calling a SOAP method ....................................................................................... 89 Input Parameters ................................................................................................. 90 Declaration of Return Parameter ......................................................................... 98

    Renaming SOAP Methods ...................................................................................... 107 Declaration Modifier const ....................................................................................... 107 Defining the Target in the Declaration of a Method ................................................ 108

    6 ACS Bus Messages ....................................................................... 109 Declaration and Sending of Bus Messages ............................................................ 109

    Asynchronous Bus Messages ............................................................................ 109 Message Name and Input Parameters .............................................................. 110 Sending Bus Messages ..................................................................................... 111 Declaration of Input Parameters ........................................................................ 112 Declaration of Return Parameters ..................................................................... 118

    Error Handling ......................................................................................................... 121

    7 Compatibility ................................................................................. 122 Web Methods .......................................................................................................... 122

    Expressions as Arguments to Web Method Calls .............................................. 122 SOAP Calls: Automatic Handling of Structs and Arrays .................................... 122 Duplicate Web Method Declarations.................................................................. 123 SOAP Calls: Parsing WSDL .............................................................................. 123

    Structs and Arrays ................................................................................................... 124 Structs ................................................................................................................ 124 Arrays ................................................................................................................. 125

    8 MAP_Delete: An Interplay | MAM Workflow ................................ 126

    Disclaimer ...................................................................................... 130

  • Using This Reference

    Congratulations on your purchase of Avid® Interplay® | Media Asset Manager (Interplay | MAM), a powerful system for archiving and managing media in a shared storage environment. This documentation is about Simple Workflow Definition Language (SWoDL). SWoDL is a script language that describes workflows in the Interplay MAM WorkflowEngine.

    Symbols and Conventions Avid documentation uses the following symbols and conventions:

    Symbol or Convention Meaning or Action

    A note provides important related information, reminders, recommendations, and strong suggestions.

    A caution means that a specific action you take causes you to lose data.

    Courier Courier on gray background indicates code examples.

    Courier blue font Courier blue font on gray background emphasizes code in examples.

    The arrow indicates that line breaks in code examples are not allowed when using or writing comparable code.

    Italic font Italic font is used to emphasize certain words.

    Courier bold font Courier bold font identifies text that you type.

    > This symbol indicates menu commands (and subcommands) in the order you select them. For example, File > Import means open the File menu and then select the Import command.

    This symbol indicates a single-step procedure. Multiple arrows in a list indicate that you perform one of the actions listed.

    Angle brackets indicate placeholders or variables.

    UPPER CASE Indicates names of processes, process classes, data model attributes, legal lists, legal list values, states of tasks, and templates.

  • 6

    If You Need Help

    If you are having trouble using your Avid product:

    1. Retry the action, carefully following the instructions given for that task in this guide. It is especially important to check each step of your workflow.

    2. Check the latest information that might have become available after the documentation was published.

    You should always check online for the most up-to-date documentation because the online version is updated whenever new information becomes available. To view the online versions, visit the Knowledge Base at www.avid.com/support.

    3. Check the documentation that came with your Avid application or your hardware for maintenance or hardware-related issues.

    4. Visit the online Knowledge Base at www.avid.com/support. Online services are available 24 hours a day, 7 days a week. Search this online Knowledge Base to find answers, view error messages, access troubleshooting tips, download updates, and read or join online message-board discussions.

    Avid Training Services

    Avid makes lifelong learning, career advancement, and personal development easy and convenient. Avid understands that the knowledge you need to differentiate yourself is always changing, and Avid continually updates course content and offers new training delivery methods that accommodate your pressured and competitive work environment.

    For information on courses/schedules, training centers, certifications, courseware, and books, please visit www.avid.com/support and follow the Training links, or call Avid Sales at 800-949-AVID (800-949-2843).

    http://www.avid.com/supporthttp://www.avid.com/supporthttp://www.avid.com/support

  • 1 Introduction

    The following topics provide information about the use of SWoDL in Interplay | MAM:

    • Basic Language Elements

    • Built-in Functions

    • HTTP POST Web Methods

    • SOAP Web Methods

    • ACS Bus Messages

    • Compatibility

    • MAP_Delete: An Interplay MAM Workflow

  • 2 Basic Language Elements

    The following table contains links to the topics that describe the basic SWoDL element.

    Topics “ Topics continued

    Command Separator, Identifiers Labels, Goto, Gosub, and Return

    Comments Exit

    Status Definitions Error

    Literals Delay

    Variables and Constants Suspend

    Structs and Arrays Try-catch, Throw, and Assert

    Arrays Conditional Command: If – Then – Else

    Expressions Loops

    Command Blocks

    Command Separator, Identifiers

    Commands are separated by a semicolon.

    An identifier in SWoDL consists of a leading letter or underscore followed by any number of alphanumeric characters or underscores.

    Examples:

    myvar _some_variable CurrentOrderStatus var4711 ASoapFunction

  • Status Definitions

    9

    Comments

    Comments are used in the same way as in C# or C++. There are two kinds of comments:

    • Line comments start with double slashes and end at the current line.

    Examples:

    // some comment goto somelabel; // another comment

    • Block comments start with /* and end with */. A Block comment can cover more than one line.

    Example:

    /* a large comment explaining for example the semantics of a function call */

    Nested block comments are not allowed.

    Status Definitions

    When writing a workflow it is good practice to use states and transitions to specify basic behavior. In a second step you refine the basic behavior to the actual SOAP calls and loops and expressions. SWoDL allows you to keep the original state information in the workflow. For this purpose you can include a status definition statement.

    Example:

    [[Waiting for analysis]]

    When executing the workflow, the status changes to “Waiting for analysis” as soon as the execution passes that definition; then you can see the new workflow status in the Workflow Monitor.

    If you use status definitions wisely, you can easily monitor the progress of your workflows.

  • Literals

    10

    Literals

    The following sections describe SWoDL literals:

    • String Literals

    • Integer Literals

    • Floating-Point Literals

    • Boolean Literals

    String Literals

    A string literal is any set of characters enclosed in double quotes.

    Example:

    "some test string"

    Double Quotes in String Literals

    To add double quotes to a string literal:

    Escape the double quotes with a single backslash.

    Example:

    "some \"quoted\" string"

    This is a string literal containing the string: some "quoted" string

    Backslashes in String Literals

    To add backslashes in string literals:

    Escape the backslash with another backslash.

    Example:

    "a string with one slash \\ and two slashes \\\\ and three slashes \\\\\\"

  • Literals

    11

    Each double backslash represents one single slash in the string; that is, the string literal in the example defines the string: a string with one slash \ and two slashes \\ and three slashes \\\

    Integer Literals

    Integer literals consist of any number of decimal digits.

    Examples:

    42 4711 3

    Beginning with WorkflowEngine V2.3.2, all integer calculations use signed 64-bit integer variables. This limits the range of values from –9.223.372.036.854.775.808 to 9.223.372.036.854.775.807. Versions before 2.3.2 used signed 32-bit integer variables, limiting the range from –2.147.483.648 to 2.147.483.647 (with the known bug: “–2147483648” could not be used as literal).

    Floating-Point Literals

    SWoDL has supported floating-point literals and operations since Interplay MAM 3.3. Floating-point literals consist of any number of decimal digits followed by a decimal point, followed by any number of decimal digits.

    Examples:

    42.5 0.234 -4.5

    Boolean Literals

    The following keywords are reserved for Boolean values.

    true false

    In expressions, the following values evaluate to true:

  • Variables and Constants

    12

    • the Boolean literal true

    • the string “true,” case-insensitive

    • all integer literals except 0

    • all floating point literals except 0.0

    • all strings containing an integer or floating point number that is not equal to 0

    All other values evaluate to false.

    Example:

    // True: if(true) { } if("True") { } if(1) { } if(-5) { } if(-0.01) { } if("17") { } // False: if(false) { } if("false") { } if("tanstaafl") { } if(0) { } if(0.0) { } if(-0.0) { } if("0") { }

    Variables and Constants

    Any valid identifier is assumed to be a variable.

    Examples:

    myvar _some_variable CurrentOrderStatus var4711

    SWoDL requires that all variables are defined before use.

    SWoDL variables are not type-safe. All variables are treated as strings. Cast operators are available. This is vital for operators like + or compare operators. See “Type Considerations” on page 28 for details.

  • Variables and Constants

    13

    The following sections describe SWoDL variables and constants:

    • Variable Declaration

    • Assigning a Value to a Variable

    • Constants

    • System Variables

    Variable Declaration

    Variables must be declared before use. This informs WorkflowEngine clients about the workflow parameters that are available so that they can be set. A variable declaration uses either the var or the in keyword.

    Examples:

    var myvar1; in DMGUID; var myvar2 = "initial value";

    The third variant initializes the variable with the given value.

    SWoDL does not support the concept of a visibility scope. All variables are global variables and visible anywhere in the workflow, no matter where they are declared.

    You can declare variables using the keyword in instead of var. Variables declared using in are input variables to the workflow. They are shown differently on the Workflow Monitor when starting a workflow:

  • Variables and Constants

    14

    The four variables shown in the upper section are in variables, those in the lower section are var variables. Apart from that, both types are handled in exactly the same way.

    Interplay MAM 3.3.2 introduced a comma-separated list of variables with one declaration.

    Example:

    var v1, v2, v3; var v1 = "Example", v2 = "Hello, world!";

    Assigning a Value to a Variable

    Assigning a value to a variable works as in C# or C++.

    Examples:

    myvar = 5; myvar = "text"; myvar2 = myvar; myvar = 5 + 7; myvar += 3.5; myvar2 = "myvar contains " + myvar myvar3 = "9"; myvar4 = (int)myvar3 * 7; myvar = substr(myvar2, 10);

    For information about operators, see “Operators” on page 27.

  • Variables and Constants

    15

    Constants

    Interplay MAM 3.3.2 introduced the definition of constants. You can define a constant by using the keyword const.

    Example:

    const pi = 3.14159265; const productname = "Interplay MAM";

    Constants are used exactly like variables, with the following restrictions:

    • A constant must be initialized with a value.

    • The value must be a literal of any type.

    • Expressions are not allowed as values.

    • Other assignments to a constant are not allowed.

    The Workflow Monitor shows a checkbox to show or hide constants in the details of a workflow.

    System Variables

    Variable names that begin with an underscore are reserved for internal use by WorkflowEngine. Unless you want to access one of these system variables, you should not use variable names that begin with an underscore. It is possible that future SWoDL versions will require additional internal WorkflowEngine variables.

    The following list of system variables is only a snapshot, and may be extended in the future.

    Variables Used in Workflows

    If the variable is not marked as “modifiable” you should never try to set the variable. Setting the variable may cause serious damage.

    Variable Modifiable Description

    _DebugMode yes Enables the debug mode. If set to “1”, the workflow is suspended after each step. Default is “0”.

    _ExceptionReason yes Exception reason (if set) — for example, “Client.DataManagerWS.UnknownObject”. The value can be used to distinguish different specific exceptions.

  • Variables and Constants

    16

    Variable Modifiable Description

    _HistorySize yes Maximum size of the _SWoDLHistory variable containing the history of executed SWoDL lines. Default is 2000. Setting the variable to very large values may result in memory shortage and performance issues.

    _JobID no The ID of the workflow.

    _Priority yes Scheduling priority for the workflow. Workflows with higher priority are executed more quickly than those with lower priority. Default is “100”.

    _RetryDelay yes Gives the delay in seconds in retry loops. Default is “30”.

    _SoapTimeout yes Defines the timeout, in seconds, for following SOAP calls. Default is the number defined in the configuration setting “WorkflowEngine/SoapCallTimeoutInSeconds”.

    _UserGuid yes Not used by WorkflowEngineWS, but the value can be displayed in the “Browse” view of Workflow Monitor. The value is trimmed to 64 characters when it is stored in the database. It may have more than 64 characters while the workflow is running, but if the workflow is suspended or finishes, or if WorkflowEnigneWS is restarted, the value is trimmed to 64 characters.

    Variables Used Internally or to Monitor Workflows

    You should not set the following variables unless you know exactly what you are doing. This is only a snapshot of the meaning of the variables. Future versions might use variables in a different way, introduce new variables, or abandon the utilization of existing variables.

    Variable Description

    _ActivityLimiter Number of times the activity limiter was triggered. WorkflowEngine limits the number of steps a workflow may execute per second. This avoids congestion in the case of unintended endless loops.

    _CallerIPAddress IP address of the PC that initially created the workflow.

    _ErrorMessage Contains the error message set with the “error” statement.

    _ErrorNumber Internal error number.

  • Variables and Constants

    17

    Variable Description

    _ExceptionMessage Message of last SOAP exception.

    _ExceptionOccured Contains 1 if a SOAP exception occurred recently. The variable is used internally to handle exceptions.

    _LastModified Date and time of last modification to the workflow.

    _SoapLimiter Number of times the SOAP limiter was triggered. WorkflowEngine limits the number of SOAP calls a workflow may execute per second. This avoids congestion of the entire Interplay MAM system in the case of unlimited loops with SOAP calls.

    _State The status of the workflow. Possible values:

    0: ready 1: ready for running 2: finished 3: suspended 4: error 5: ready with problems

    Usually only the values 0, 2, 3, and 4 are used.

    _Name Workflow template used for this workflow.

    _NextActivity Number of next activity to be executed (only used internally).

    _NextStartTime Next start time in case of delays.

    _NumActivities Counter for number of executed activities (only used internally).

    _Owner Name of the WorkflowEngineWS instance that currently owns the workflow.

    _ReturnStack Stack of return addresses for gosub and return calls.

    _RunTime Total runtime of workflow, in milliseconds.

    _StartUpTime Time when the workflow was created.

    _SWoDLHistory Execution history in terms of line numbers of the SWoDL description of the workflow.

    _SWoDLLineNumber Number of the currently executed line in SWoDL description.

    _WorkflowStatus Externally visible description of the workflow status, set using a “[[some text]]” statement.

  • Structs and Arrays

    18

    Structs and Arrays

    SWoDL supports structs and arrays as built-in data types. Both are stored like any other variable, but with an XML document in a specific format as content.

    Structs

    Interplay MAM 3.4.3.2 introduced structs as a new concept in SWoDL. Structs are handled similarly to JavaScript. If you have an ordinary variable, you can introduce a new field with a dot notation.

    Example:

    var user; user.JobTitle = "Businessman"; user.Age = 55; user.FullName.FirstName = "Joe"; user.FullName.LastName = "Satriani";

    This defines user as a struct that has the following members:

    • JobTitle

    • Age

    • FullName

    FullName in turn is a struct that has the members:

    • FirstName

    • LastName

    The individual members of the struct do not appear in the list of variables in the Workflow Monitor. They are dynamically read from the XML content during runtime.

    You can use a member of a struct like any regular variable — for example, in an expression or as parameter of a Web method.

    Example:

    var age = user.Age;

    If you access a field that does not exist, it returns an empty string.

  • Structs and Arrays

    19

    Example:

    var x = user.FieldThatDoesntExist; // returns an empty string

    To avoid mistakes, you should be very careful with the exact spelling of your field names, including capitalization, as field names are case-sensitive.

    You can also assign an entire struct to a variable.

    Example:

    var secondUser = user;

    After that assignment, the variable secondUser contains a copy of the struct user. Structs are value types, not reference types.

    Implementation of structs

    This chapter explains the current implementation of structs. It is meant for informational purposes only. The implementation may be changed in future versions. You must not rely on the details of the implementation. For example, you should not pass an XML document for a struct to a Web method and parse it, relying on specifics of the XML format.

    When you are defining a regular variable, its content is stored as a simple string. When you are using the “.” delimiter to introduce a field, the variable becomes a struct and the content of the struct is stored as an XML document, such as (referencing the previous example):

    Businessman 55 Joe Satriani

    The root element of the XML document is “struct”. Each of the fields of the struct is represented by an XML element with the same name as the field — for example, 55 for the field Age.

    The field FullName in the example is itself a struct that contains the fields FirstName and LastName. This inner struct is created using the same rules, resulting in the following XML:

  • Structs and Arrays

    20

    Joe Satriani

    The XML document of that inner struct is then stored as text content in the outer struct:

    Businessman 55 Joe Satriani

    Through Interplay MAM 4.2.x, the implementation was different. See “Structs” on page 124 for details.

    Arrays

    Interplay MAM 3.4.3.2 introduced arrays as a new concept in SWoDL. Arrays are implemented by a set of built-in functions. The content of an array is stored as an XML document. The following table lists the functions:

    Function Description

    x[i] Accesses the ith element of the array x.

    array_create() Creates an array (returns an empty array XML). The call is often redundant, because SWoDL treats an empty string as an empty array when using the array functions.

    array_add(array, value) Returns a copy of the given array with the new value added to the end of the array. The array given as first parameter is not changed.

    array_get(array, index) Gets the value of the element with the given index in the array. If the index is not available in the array, the function returns an empty string.

    array_isset(array, index) Returns true if the index is set in the array.

    array_bounds_lower(array) Returns the lowest index in the array.

    array_bounds_upper(array) Returns the highest index in the array.

    array_size(array) Returns the size of the array (the number of elements that have been set).

  • Structs and Arrays

    21

    Function Description

    array_set(array, index, value) Returns a copy of the given array, where the value of the item with the given index in the array is set to the given value.

    For the array_get and array_set methods, the simpler and easier syntax with square brackets is available, as shown in the following examples:

    Example 1:

    var a = array_create(); a = array_set(a, 0, "astring"); a[0] = "astring"; // same as: a = array_set(a, 0, "astring"); var value = array_get(a, 0); value = a[0]; // same as: value = array_get(a, 0);

    Example 2:

    var a = array_create(); a[3] = "string #3"; a[5] = "string #5"; a[7] = "string #7"; // ------------------------ // bounds and size methods: // ------------------------ var bl = array_bounds_lower(a); // returns 3 var bu = array_bounds_upper(a); // returns 7 var size = array_size(a); // returns 3 // --------------------------- // typical loop over an array: // --------------------------- var i=array_bounds_lower(a); while( i

  • Structs and Arrays

    22

    details of the implementation. For example, you should not pass an XML document for an array to a Web method and parse it, relying on specifics of the XML format.

    The content of an array is stored as an XML document with root element “itemsOfArray”. The root element has one “item” element for each item in the array. Each item has an XML attribute “index”, which gives the index number of the item.

    Example:

    var x; x[0] = "First item"; x[1] = "Second item";

    This results in the following XML document:

    First item Second item

    Combining Structs and Arrays

    You can combine structs and arrays in any way you want. The following example creates a struct that contains information about the movie Brazil, including an array of actors. The name and role name are stored for each actor.

    Example:

    var movie; movie.Title = "Brazil"; movie.Director = "Terry Gilliam"; movie.Actors[0].Name = "Jonathan Pryce"; movie.Actors[0].RoleName = "Sam Lowry"; movie.Actors[1].Name = "Robert De Niro"; movie.Actors[1].RoleName = "Harry Tuttle"; movie.Actors[2].Name = "Kim Greist"; movie.Actors[2].RoleName = "Jill Layton"; // Get name of the first actor: var firstActor = movie.Actors[0]; var nameOfFirstActor = firstActor.Name;

  • Structs and Arrays

    23

    // Get name of the second actor: var nameOfSecondActor = movie.Actors[1].Name;

    The example shows that you can mix the square bracket operator that accesses an item of an array with the dot operator that accesses a field of a record.

    Use of these operators was restricted in Interplay MAM through 4.2.x. See “Arrays” on page 125 for details.

    Implementation of nested arrays and structs

    An array is stored as an XML document with root element “itemsOfArray”. The root element has one “item” element for each item in the array. Each item has an XML attribute “index”, which gives the index number of the item.

    If an item itself is a struct, the content of the struct is serialized as an XML document as explained in “Structs” on page 18. This inner document is then stored as the text value of the node.

    Example:

    var x; x[0] = "First item"; x[1].a = "A value"; x[1].b = "A second value";

    This results in the following XML document:

    First item A value A second value

    The same happens if an item of an array is itself an array:

    var a; a[0][0] = "First sub item of item 1"; a[0][1] = "Second sub item of item 1"; a[1] = "Item 2";

    This results in the following XML document:

  • Structs and Arrays

    24

    First sub item of item 1Second sub item of item 1 Item 2

    The item with index 0 contains an array with two elements. The XML representation of the inner element is stored as text content of the item 0.

    Using Arrays and Structs to Parse XML Documents

    When creating arrays and structs in SWoDL, the data is stored in the well-defined XML format described in the previous chapters. However, the implementation of arrays and structs is more flexible when parsing XML documents. It supports not only its own XML schema, but, in a lot of cases, also allows parsing XML documents using other schemas.

    Example: The variable doc contains the following XML document:

    1 123 456 0 1 2

    The following evaluation rules apply:

    Access type Example Description

    Struct doc.a Searches the first XML child element of the document node that has the same local name as the field name (here, “a”).

    • If that element has sub-elements, the element is returned with all sub-elements. XML namespaces are kept.

    • If that element has no sub-elements, the text content of the node is returned.

    Examples:

    • doc.a finds the XML element in the document. has

  • Structs and Arrays

    25

    Access type Example Description

    no sub-elements, so the method returns the text content of a, which is “1”.

    • doc.b finds the XML element in the document. has sub-elements, so the result is the XML fragment “123456“.

    Array doc[0]

    If you use the square bracket operator on an XML document, SWoDL interprets all child elements of the document element as items, independent of the name of the element. In the example, the result is a total of three items, one for each of the child elements , , and . doc[0] selects the first of the three elements. In the example, this is the XML element .

    • If that element has sub-elements, the element is returned with all sub-elements. XML namespaces are kept.

    • If that element has no sub-elements, the text content of the node is returned.

    Examples:

    • doc[0] finds the first child element. In the example, this is the XML element . The element has no sub-elements, so the method returns the text content of a, which is “1”.

    • doc[1] finds the second child element. In the example, this is the XML element . The element has sub-elements, so the result is the XML fragment “123456“.

    There’s one special case: If the root element is “itemsOfArray” and the child items have the name “item” and an XML attribute “index”, then the item is interpreted as an item with that index value. This corresponds to the format used to store an array in SWoDL.

    Combined doc.b.f1

    doc.c[0]

    The evaluation rules ensure that you can combine the dot and square bracket operators in a natural way.

    Examples:

    • doc.b.f1 selects the element below the element and returns the content, which is “123”.

    • doc.c[0] selects the first element (index 0) below the element and returns its content, which is “0”.

    XML namespaces are ignored when evaluating the documents. In the end, you can parse most XML documents in a natural way.

  • Structs and Arrays

    26

    Example: The (abbreviated) result of a call to the EssenceManager method GetEMObjectWithLocations:

    262a3eb6-ddf8-4b52-acc5-4c126438c78d MP4 c3ca04a3-ee21-482f-875d-7994d533b949 1003 f827c043-d6b3-433d-be71-0db03a2c1abf 1001

    You can access the elements like this:

    // declare method and call it var EssenceManagerWS_EssenceManager = "EssenceManagerWS/EssenceManager"; declare soap _auto GetEMObjectWithLocations(accesskey, emguid); var response = GetEMObjectWithLocations(AccessKey, "262a3eb6-ddf8-4b52-acc5-4c126438c78d") @ EssenceManagerWS_EssenceManager; // Get streamtype (sub element streamtype of element emobj): var streamType = response.emobj.streamtype; // Get number of locations below node: var numberOfLocations = array_size(response.locations); // Get first of the locations. The result is the XML fragment // … of the first returned EMLocation: var firstLocation = response.locations[0]; // Fetch the carrierguid from the first location: var carrierOfFirstLocation = firstLocation.carrierguid; // get carrierguid of second location: var carrierOfSecondLocation = response.locations[1].carrierguid;

  • Expressions

    27

    Expressions

    The following sections describe SWoDL expressions:

    • Operators

    • Type Considerations

    • Cast Operators

    • Pitfall: Variables May Change Operation Type

    Operators

    SWoDL supports the usual operators that are available in most modern languages, and in the usual precedence.

    Operator Name Operator Sign

    Unary - !

    Casts (int) (bool) (string) (float)

    Multiplicative * / %

    Additive + -

    Shift >

    Relational < > =

    Equality == !=

    Logical AND &

    Logical XOR ^

    Logical OR |

    Conditional AND &&

    Conditional OR ||

    Assignment = *= /= %= += -= = &= ^= |=

    Floating-point arithmetic was introduced in Interplay MAM 3.3.

    The following operators have a different meaning when used with strings:

  • Expressions

    28

    Operator Name Operator Sign

    Concatenation +

    Relational: string comparison < > =

    Assignment with concatenation +=

    You can also use parentheses to group your expressions.

    Example:

    3 * (4 + 5 – (4 * 7))

    Type Considerations

    All operators may be used for floating-point or integer arithmetic; some may additionally be used for string operations. The type of operation is defined by the type of operands.

    It is very important to know that SWoDL variables are always treated like string variables. Even after assigning an integer value to a variable, it is treated as a string variable that contains the string representation of the integer value.

    The basic rule for the selection of the type of operation works as follows:

    1. If the operator is one of the string operators, and both operands are strings, the string operation is used.

    2. If one of the operands is a double value or a string that can be interpreted as a double value (contains digits, followed by a dot, followed by digits), the double operation is used.

    3. Otherwise, the integer operation is used.

    Examples:

    "a" + "b"// Rule 1: string operation (concatenation) 5.3 + "4"// Rule 2: double operation “5.3” + "4"// Rule 1: string operation (concatenation) 3 + "4"// Rule 3: integer operation 3 / "4.0"// Rule 2: double operation (“4.0” can be interpreted as // double) "3" / "4"// Rule 3: integer operation (“/” can’t be string op) "3" / "4.5"// Rule 2: double operation

  • Expressions

    29

    var x = 4.5; var y = 3; x + y;// Rule 1: string operation (because all variables are //treated as string) x / y;// Rule 2: double operation (because x contains "4.5" => //can be interpreted as double) y + 1;// Rule 2: integer operation (because 1 is not a string) y + (3 * x)// *: integer, +: integer

    The last example shows that while evaluating an expression, the type is relevant. 3*x is evaluated using an integer operation, so the result is an integer. According to rule 3, the + operation in this case is also an integer operation, because the second operand (result of 3*x) is an integer value.

    Cast Operators

    You can always use cast operators to explicitly set the type of an operand.

    Example:

    (int) x + (int) y// integer operation (because of type casts) (float) 4 / 3// floating point operation 4 / (float) 3// floating point operation (float) 3 + "4"// string operation (bool) y

    Pitfall: Variables May Change Operation Type

    A very common mistake occurs when using loops in SWoDL. Consider the following examples:

    Example 1:

    var counter = 0; while( counter < 10 ) { // do something counter+=1; }

    This works perfectly well. The “

  • Command Blocks

    30

    Example 2:

    var counter = 0; var maxNumber = 10; while( counter < maxNumber ) { // BAD!!! // do something counter+=1; }

    This fails, because now “

  • Labels, Goto, Gosub, and Return

    31

    Labels, Goto, Gosub, and Return

    Labels and Goto

    SWoDL supports the goto command by means of definable labels. A label is defined by an identifier followed by a colon. A goto command consists of the keyword goto followed by a label and a semicolon.

    Example:

    goto mylabel; // do something mylabel: // do something else

    Gosub and Return

    SWoDL 2.2 supports the BASIC-like commands gosub and return in Interplay MAM 3.2.1. They are used for simple subroutines in a workflow.

    Example:

    // do some stuff gosub brewCoffee; // do more stuff brewCoffee: // do something useful return;

    The gosub command jumps to a given label exactly as the goto call. The only difference is that the return address is stored in a system variable in the workflow. When the return command is executed, WorkflowEngine automatically continues with the next statement after the gosub call.

  • Suspend

    32

    Exit

    The exit command terminates the workflow.

    Example:

    exit;

    Error

    The error command terminates the workflow with the status ERROR and sets the variable _ErrorMessage to the given text.

    Example:

    error "Somewith went wrong";

    Delay

    A delay command pauses the workflow for the given number of seconds. Argument can be either a literal or a variable.

    Examples:

    delay 10; delay delayInSeconds;

    Suspend

    The suspend command suspends the workflow.

    Example:

    suspend;

    There is no timeout for the suspension. The workflow is reactivated when someone calls the wakeup method of WorkflowEngine for that workflow. Currently this is used in connection

  • Try-catch, Throw, and Assert

    33

    with OrderManagement. The workflow suspends itself and is reactivated by OrderManagement when the status of an order has changed.

    Try-catch, Throw, and Assert

    SWoDL can catch exceptions that occur when calling Web methods. For information about Web methods, see “HTTP POST Web Methods” on page 75 and “SOAP Web Methods” on page 86.

    Example:

    try { // commands... } catch { // handle exception }

    If an exception occurs outside of a try-catch block, the workflow is terminated with status “error”.

    try-catch blocks can be nested. In this case the innermost exception handler is executed.

    Interplay MAM 3.3 introduced the new throw command, allowing you to explicitly throw an exception.

    Example:

    try { throw "Some text"; } catch { // handle exception }

    Interplay MAM 3.3 introduced the the assert command. It asserts a condition (in the example, myvar==42). If the condition is not met, the assert command throws an exception.

    Example:

    try { assert(myvar==42, "myvar is not 42"); } catch { // handle exception }

  • Loops

    34

    This is useful in cases where you “know” that some condition must be true, but you want to check the condition to be absolutely sure. You can also use it to simplify the structure of your workflow, and for SWoDL scripts that implement automated integration tests.

    Conditional Command: If – Then – Else

    SWoDL supports the typical if-then-else semantics in the same way as in C# or C++.

    Example:

    if( myvar == 1 ) goto labelA; if( myvar == 3 ) goto labelB; else goto labelC;

    Usually, command blocks are used together with conditional commands.

    Example:

    if( myvar == 0 ) { p = 42; } else if( myvar == 3 ) { p = 23; } else { p = 0; }

    Loops

    The following sections describe SWoDL loops:

    • While Loop

    • Do-while Loop

    • Retry-while Loop

  • Loops

    35

    While Loop

    The while loop repeats a command as long as a condition is fulfilled. The condition is checked before the command is executed. The while loop is not entered if the condition is not fulfilled.

    Examples:

    var i=0; while(i < array_size(a)) { // do something i += 1; }

    Do-while Loop

    The do-while loop repeats a command as long as the condition is fulfilled. The condition is checked after the command has been executed.

    Example:

    do { myvar = SOAPCall() @ EM; } while(myvar != 0);

    Retry-while Loop

    The retry-while loop works like the do-while loop, with two differences:

    • If the while condition is true, the next execution of the loop is delayed. This is useful when calling a SOAP method until the call succeeds, for example. The delay is defined by the value of the variable _RetryDelay (unit: seconds). The initial value of _RetryDelay is 30.

    • The retry-while loop includes a try-catch exception handler around the looped commands. All exceptions are simply ignored.

    Example:

    retry { result = OMA_SetOrderStatus(jobID, "newStatus"); } while( result != false);

  • Loops

    36

    It is possible to define a maximum number of tries for a retry-while loop.

    Example:

    retry(10) { result = OMA_SetOrderStatus(jobID, "newStatus"); } while( result != false);

    After 10 tries the loop exits, regardless of the while condition. The number of tries can be any valid SWoDL expression, such as a variable.

    If the loop has no maximum number of tries defined, the loop does not end until the while condition is met. If the while condition does not evaluate to true, an endless loop was created.

  • 3 Built-in Functions

    SWoDL supports a set of built-in functions to be used in expressions. They are described in:

    • String Handling

    • XML Functions

    • Regular Expressions

    • Handling Lists: getelement, getnumberofelements

    • Random Number Generation

    • Floating-Point Functions

    • Empty Operation: nop

    String Handling

    Handling strings is described in the following sections:

    • String Comparison: compare

    • Extracting Part of a String: substr

    • Length of a String: length

    • Find a Substring in a String: find

    • Find Last Occurrence of a Substring: findreverse

    • XML Encoding and Decoding: xmlencode and xmldecode

    • Trim a String: trim

    • Replace Substrings: replace

  • String Handling

    38

    String Comparison: compare

    The method compare compares two strings. It corresponds to the .NET method string.Compare.

    Example:

    result = compare(str1, str2);// case-sensitive result = compare(str1, str2, true); // case-insensitive

    This call compares two strings lexicographically and according to case-sensivity. It returns -1 if the first string is less than the second, 0 if they are equal, and 1 if the first string is greater than the second.

    The method can be called with an additional Boolean parameter: If the third parameter is set to false, the method behaves as the two-parameter method. If the third parameter is true, the strings are compared case-insensitive.

    Extracting Part of a String: substr

    The method substr extracts a part of a given string. It corresponds to the .NET method String.Substring.

    Example:

    str1 = "An example string"; s1 = substr(str1, 5); // returns "ample string" s2 = substr(str1, 5, 3); // returns "amp"

    The first parameter is the source string. The second parameter is the start position (first character is position 0). The optional third parameter is the length of the extracted part. If the third parameter is missing, the method returns the rest of the string, beginning with the start position.

    The method throws an exception if the start position or start position + length are out of the bounds of the string str1.

    This exception cannot be caught by a try-catch statement. The SWoDL workflow terminates with error status.

  • String Handling

    39

    Length of a String: length

    The method length returns the length of a string.

    Example:

    len = length("test"); // returns 4

    Find a Substring in a String: find

    The method find returns the first occurrence of a pattern string in a string. It corresponds to the .NET method String.IndexOf.

    Example:

    str = "a large string"; pattern = "large"; pos = find(str, pattern); // returns 2 pos2 = find(str, "doesn’t exist in str"); // returns –1 -> not found

    The strings are compared according to case-sensitivity. If the pattern string cannot be found the method returns –1.

    You can provide a third parameter to determine the start position in the string.

    Example:

    pos3 = find(str, "a", 2); // returns 3

    Find Last Occurrence of a Substring: findreverse

    The method findreverse returns the last occurrence of a pattern string in a string. It corresponds to the .NET method String.LastIndexOf. In all other aspects the method works like find.

    Example:

    str = "a large string"; pattern = "a"; pos = findreverse(str, pattern); // returns 3 pos2 = findreverse(str, pattern, 2); // returns 0

  • XML Functions

    40

    Trim a String: trim

    The trim method removes white space characters from the beginning and end of a string.

    Example:

    result = trim(" a string "); // returns "a string"

    Replace Substrings: replace

    The replace method replaces all occurrences of a pattern string by a string.

    Example:

    result = replace("hurliburli", "url", "ping"); // returns "hpingibpingi"

    XML Functions

    Handling XML documents is described in the following sections:

    • XML Encoding and Decoding: xmlencode and xmldecode

    • Parsing XML documents

    • Creating XML documents

  • XML Functions

    41

    XML Encoding and Decoding: xmlencode and xmldecode

    xmlecode

    The method xmlencode encodes the XML special characters to their encoded counterparts, as shown in the table:

    Character Character name XML encoding

    & ampersand &

    " double quotation mark "

    ' apostrophe '

    < less-than sign <

    > greater-than sign >

    Example:

    result = xmlencode(“”); // returns “”

    xmldecode

    The method xmldecode is the counterpart of xmlencode. It converts encoded characters back to their original values.

    Example:

    result = xmldecode(“”); // returns “”

    Both methods are supposed to be used when manually creating XML “strings” via string operations, and when creating XML documents using the xml_new_element method.

    Example:

    var metaValue = "Rock'n Roll"; var xml = "" + xmlencode(metaValue) + "";

  • XML Functions

    42

    Avid recommends using xmlencode for all variables when creating an XML document by means of string operations. It is a very common error to forget the encoding. SWoDL scripts frequently fail in production environments because XML special characters — such as the apostrophe in the example above — haven’t been properly encoded.

    Parsing XML Documents

    You can parse XML documents using the array and struct functionality of SWoDL. See “Using Arrays and Structs to Parse XML Documents” on page 24 for details. However, there are cases when it is better to use the XML parsing methods described in this chapter:

    • If your XML document is very large and you need to access specific nodes, it is faster to use the xml_select method and an XPath expression, because it parses the XML document only once.

    • If you want to handle XML elements that appear in different places in your XML document in one loop, it is easier and faster to use xml_select_multi and an XPath expression.

    • The SWoDL code can be easier to read if you clearly state that you are working on XML elements.

    • XML documents that contain lists of XML elements together with other XML elements on the same level can’t be handled properly with the struct and array functionality.

    • If XML namespaces are important, you must use the built-in XML methods, because XML namespaces are ignored by the struct and array functionality.

    The following sections describe functions to parse XML documents:

    • XML namespace: xml_ns

    • Getting text content: xml_text

    • Getting a child element: xml_element

    • Getting all child elements: xml_elements

    • Getting all descendants: xml_descendants

    • Getting an attribute value: xml_attribute

    • Selecting a single node via XPath: xml_select

    • Selecting multiple nodes via XPath: xml_select_multi

  • XML Functions

    43

    XML namespace: xml_ns The function xml_ns creates an XML namespace declaration:

    var ns = xml_ns("http://services.avid.com");

    Technically, the function only places curly brackets around the given parameter, but by using the function the code becomes much more readable. Typical use is the combination of an XML namespace with an element:

    var result = xml_element(xmldoc, ns + "example");

    This returns the first child element of the XML document that has the name “example” and is in the XML namespace “http://services.avid.com”.

    Getting text content: xml_text The function xml_text returns the concatenated value of all text nodes below the root node of the given XML document.

    Example:

    1 2 10 11 Test XML

    The function xml_text() returns the concatenated text values of the entire XML document:

    var text = xml_text(xml); // returns the string "121011Test XML"

    Encoded XML special characters like &, >, or < are automatically decoded by this method.

  • XML Functions

    44

    Getting a child element: xml_element The function xml_element accepts an XML document and an element name as parameter. It returns the first child element of the root element that matches the given name.

    XML namespaces are relevant. If the element has a non-empty XML namespace, you must ask for the element with the XML namespace.

    If the first argument is not a valid XML document or if there is no child element with the given name in the given XML namespace, the method returns an empty string.

    Example without namespaces: The variable xml contains the following XML document:

    1 2 10 11 Test XML

    The function xml_element is called like this:

    var elem = xml_element(xml, "example");

    The function returns the first element with name “example”:

    1 2

    Of course, you can nest xml_element calls to traverse the XML document.

    Example:

    var a = xml_text( xml_element( xml_element(xml,"example"), "a"));

  • XML Functions

    45

    // returns textual content of node "a" within node "example"

    Example with namespaces: The variable xmlWithNs contains the following XML document:

    1 2 10 11 Test XML

    The function xml_element is called like this:

    var avid = xml_ns("http://services.avid.com"); var elemWithNs = xml_element(xmlWithNs, avid + "example");

    The function returns the first element with name “example” in the XML namespace “http://services.avid.com”:

    1 2

    The XML namespaces of returned elements are preserved. For example, the node is still in the XML namespace “http://www.test.org”, as in the original XML document.

    Getting all child elements: xml_elements The function xml_elements accepts an XML document and, optionally, an element name as parameter.

    • xml_elements(xmldoc) returns an array with all child elements of the root node of the XML document.

    • xml_elements(xmldoc, elementName) returns an array with all child elements of the root node of the XML document that have the name given with the parameter elementName.

  • XML Functions

    46

    XML namespaces are relevant. If the element names have a non-empty XML namespace, add the XML namespace to the element name parameter.

    If the first argument is not a valid XML document, or if there is no child element with the given name in the given XML namespace, the method returns an empty string.

    Example without namespaces: The variable xml contains the following XML document:

    1 2 10 11 Test XML

    The function xml_elements is called like this:

    // Return all elements: var allElems = xml_elements(xml); // Return the elements with the name "example": var exampleElems = xml_elements(xml, "example");

    The first call xml_elements(xml) returns an array with the following elements:

    Item #0: 12 Item #1: 1011 Item #2: Test XML

    The second call xml_elements(xml, “example”) returns an array with the following elements:

    Item #0: 12 Item #1: 1011

    Example with namespaces: The variable xmlWithNs contains the following XML document:

  • XML Functions

    47

    1 2 10 11 Test XML

    The function xml_elements is called like this:

    // Namespace definition: var avid = xml_ns("http://services.avid.com"); // Getting all elements: var allElementsWithNs = xml_elements(xmlWithNs); // Getting all elements with name "example" in XML namespace // "http://services.avid.com": var allElementsWithNs = xml_elements(xmlWithNs, avid + "example");

    The first call xml_elements(xmlWithNs) returns an array with the following elements:

    Item #0: 1 2 Item #1: 10 11 Item #2: Test XML

    The items here are shown as a formatted and indented XML document. The elements returned by SWoDL are stored without any formatting or indentation.

    The second call xml_elements(xml, avid + “example”) returns an array with the following elements:

    Item #0:

  • XML Functions

    48

    1 2 Item #1: 10 11

    The XML namespaces of returned elements are preserved.

    Getting all descendants: xml_descendants The function xml_descendants accepts an XML document and, optionally, an element name as parameter.

    • xml_descendants (xmldoc) returns an array with all descendant elements of the document node of the XML document. This includes child nodes on any level below the document element, including child elements, grandchild elements, and so on.

    • xml_elements(xmldoc, elementName) returns an array with all descendant elements of the document node of the XML document that have the name given with the parameter elementName. This includes child nodes on any level below the document element, including child elements, grandchild elements, and so on.

    XML namespaces are relevant. If the element names have a non-empty XML namespace, add the XML namespace to the element name parameter.

    If the first argument is not a valid XML document, or if there is no child element with the given name in the given XML namespace, the method returns an empty string.

    Example: The variable xml contains the following XML document:

    1 2 10 11 Test XML

  • XML Functions

    49

    The function xml_descendants is called like this:

    // Return ALL descendant elements: var allDescendants = xml_descendants(xml); // Return all descendant elements having the name "a": var descendants = xml_descendants(xml, "a");

    The first call xml_descendants(xml) returns an array with the following elements:

    Item #0: 12 Item #1: 1 Item #2: 2 Item #3: 1011 Item #4: 10 Item #5: 11 Item #6: Test XML

    The result consists of all XML elements below the document, on any level.

    The second call xml_descendants(xml, "a") returns an array with the following elements:

    Item #0: 1 Item #1: 10

    If you use the second version with an XML document that contains XML namespaces, you must use a qualified element name using the xml_ns() function. The following example returns all elements that have the name “example” and are in the XML namespace “http://services.avid.com”.

    var ns = xml_ns("http://services.avid.com"); var descendantsWithNs = xml_descendants(xmlWithNs, ns + "example");

    Getting an attribute value: xml_attribute The function xml_attribute accepts an XML document and an attribute name as parameter. The method returns the value of the given XML attribute of the XML document’s root element.

    If the first argument is not a valid XML document or if there is no attribute with the given name, the method returns an empty string.

  • XML Functions

    50

    Example: The variable xml contains the following XML document:

    Test XML

    The function xml_attribute returns the value of the given attribute:

    var v = xml_attribute(xmlDoc, "tag"); // returns the string "value"

    You can use attribute names that are in XML namespaces by using the xml_ns function:

    var avid = xml_ns("http://services.avid.com"); var v = xml_attribute(xmlWithNs, avid + "tag");

    Selecting a single node via XPath: xml_select The method xml_select accepts at least two arguments:

    • xmlDoc: an XML document

    • xpath: an XPath expression, according to XPath version 1.0

    • namespaces: an arbitrary number (0 or more) of additional parameters; each contains an XML namespace definition

    The method extracts the first node that matches the XPath expression. If xmlDoc is not a valid XML document, or if no node matches the XPath expression, the method returns an empty string.

    Example without namespaces: The variable xml contains the following XML document:

    1 2 10 11 Test XML

  • XML Functions

    51

    The function xml_select returns the node selected by the given XPath expression:

    var xpath = "/myxml/example/a"; var selNode = xml_select(xml, xpath); // returns "1"

    Example with namespaces: The variable xmlWithNs contains the following XML document:

  • XML Functions

    52

    • xpath: an XPath expression, according to XPath version 1.0

    • namespaces: an arbitrary number (0 or more) of additional parameters; each contains an XML namespace definition

    The method extracts all nodes that match the XPath expression. If xmlDoc is not a valid XML document, or if no node matches the XPath expression, the method returns an empty array.

    Example without namespaces: The variable xml contains the following XML document:

    1 2 10 11 Test XML

    The function xml_select_multi returns an array of all nodes selected by the given XPath expression:

    var xpath = "/myxml/example/a"; var selNodes = xml_select_multi(xml, xpath);"

    This returns an array with the following items:

    Item #0: 1 Item #1: 10

    Example with namespaces: The variable xmlWithNs contains the following XML document:

  • XML Functions

    53

    Test XML

    The function xml_select_multi is called with the following arguments:

    • The XML document.

    • The XPath expression. The XPath expression in the example below uses the namespace prefixes “avid” and “t”.

    • Two parameters declaring the two namespaces, including the prefixes used in the XPath expression. You can provide an arbitrary number of namespace declarations. Each consists of a prefix like “avid”, followed by an equal sign, followed by the actual XML namespace name.

    var xpathNs = "/avid:myxml/avid:example/t:a"; var selNodesNs = xml_select_multi(xmlWithNs, xpathNs, "avid=http://services.avid.com", "t=http://www.test.org");

    This call returns an array with the following items:

    Item #0: 1 Item #1: 10

    Creating XML Documents

    SWoDL supports methods to create an XML document in a similar way to .NET.

    Example:

    var newXml = xml_new_element("myxml", xml_new_attribute("tag", "value"), xml_new_element("example", xml_new_element("a", xmlencode("1")), xml_new_element("b", xmlencode("2"))), xml_new_element("description", xmlencode("Simon & Garfunkel")));

    That code fragment creates the following XML document:

    1

  • XML Functions

    54

    2 Simon & Garfunkel

    When creating an XML document, ensure that the text for text nodes is properly XML encoded. Avid recommends using the xmlencode() function for all text elements, as shown in the example above.

    Only XML attributes that are created using the xml_attribute() method are automatically encoded properly.

    The methods can be used with XML namespaces:

    var avid = xml_ns("http://services.avid.com"); var t = xml_ns("http://www.test.org"); var newXmlNs = xml_new_element(avid + "myxml", xml_new_element(avid + "example", xml_new_element(t + "a", xmlencode("1")), xml_new_element(avid + "b", xmlencode("2"))), xml_new_element("description", xmlencode("Simon & Garfunkel")));

    This results in the following XML document:

    1 2 Simon & Garfunkel

    The following sections describe functions to create XML documents:

    • Create an XML element: xml_new_element

    • Create a new XML attribute: xml_new_attribute

    Create an XML element: xml_new_element

    The method xml_new_element expects an arbitrary number of arguments. The first argument is the name of the new XML element. The following arguments can be one of the following:

  • XML Functions

    55

    • The result of another xml_new_element() call. The XML element created by the inner call is added as child element.

    • The result of a call to xml_new_attribute(). The attribute is added as XML attribute.

    • A string containing an XML document. The document is added as child element.

    • A string that is not parseable as XML document. Avid strongly recommends only passing strings encoded using the xmlencode() method.

    Example 1: Create a new XML element:

    var newElem = xml_new_element("example"); // Returns:

    Example 2: Create a new XML element in an XML namespace:

    var avid = xml_ns("http://services.avid.com"); var newElemNs = xml_new_element(avid + "example"); // Returns:

    Example 3: Create a new XML element with the following sub-elements:

    • an XML attribute

    • an inner XML element

    • an embedded XML fragment

    • a text node, properly encoded using xmlencode

    var newElemWithSubElements = xml_new_element("example", xml_new_attribute("tag", "value"), xml_new_element("description"), "", xmlencode("Simon & Garfunkel")); // Returns (formatted for better readability): // // // // // // Simon & Garfunkel //

  • XML Functions

    56

    Example 4: Create a new XML element in the namespace “http://services.avid.com” with the following sub-elements:

    • an XML attribute in the same namespace

    • an inner XML element in the same namespace

    • an embedded XML fragment in the empty namespace

    • a text node, properly encoded using xmlencode

    var avid = xml_ns("http://services.avid.com"); var newElemWithSubElementsNs = xml_new_element(avid + "example", xml_new_attribute(avid + "tag", "value"), xml_new_element(avid + "description"), "", xmlencode("Simon & Garfunkel")); // Returns (formatted for better readability): // // // // // // Simon & Garfunkel //

    WorkflowEngineWS creates XML namespace prefixes like the “p1” in the example, as needed.

    Example 5: This is the same as the previous example, but now we define the XML namespace prefix by adding an appropriate “xmlns:prefixName” attribute to the element:

    var avid = xml_ns("http://services.avid.com"); var newElemWithSubElementsNs = xml_new_element(avid + "example", xml_new_attribute("xmlns:avid", "http://services.avid.com"), xml_new_attribute(avid + "tag", "value"), xml_new_element(avid + "description"), "", xmlencode("Simon & Garfunkel")); // Returns (formatted for better readability): // //

  • XML Functions

    57

    // // // // Simon & Garfunkel //

    Create a new XML attribute: xml_new_attribute The function xml_new_attribute() is used to create a new XML attribute to be added to an XML element. The function can only be used in connection with the xml_new_element() function.

    Example 1: Create a new element with two attributes:

    var newElem = xml_new_element("example", xml_new_attribute("tag", "value"), xml_new_attribute("performed_by", "Simon & Garfunkel")); // Returns: //

    Example 2: Create a new element with two attributes, one of them using an XML namespace:

    var avid = xml_ns("http://services.avid.com"); var newElem = xml_new_element("example", xml_new_attribute(avid + "tag", "value"), xml_new_attribute("performed_by", "Simon & Garfunkel")); // Returns: //

    Technically, the xml_attributes() method creates an XML fragment with a magic value as element name:

    var xmlFragment = xml_new_attribute("tag", "value"); // Returns: // var avid = xml_ns("http://services.avid.com"); var xmlFragmentNs = xml_new_attribute(avid + "tag", "value"); // Returns: //

    The implementation of the xml_new_element method transforms that fragment to an XML attribute.

  • XML Functions

    58

    Add child elements: xml_add

    The function xml_add() adds child elements to the root element of an XML document. The first argument is the XML document. The following arguments are the child elements to be added. They can be one of the following:

    • The result of an xml_new_element() call. The XML element created by the inner call is added as a child element.

    • The result of a call to xml_new_attribute(). The attribute is set as an XML attribute to the root element of the XML document.

    • A string containing an XML document. The document is added as a child element.

    • A string that is not parseable as an XML document. Avid strongly recommends only passing strings that are encoded using the xmlencode() function.

    The function does not modify the XML document that is given as the first argument. It returns the modified XML document as the result value.

    Examples:

    var xml = "5"; // 1.) Add a child element: var modifiedXml = xml_add(xml, xml_new_element("b", "abc")); // returns: 5abc // 2.) Add an attribute: var modifiedXml2 = xml_add(xml, xml_new_attribute("id", "1")); // returns: 5 // 3.) Add an XML fragment: var modifiedXml3 = xml_add(xml, "xyz"); // returns: 5xyz // 4.) Add an XML text node: var modifiedXml4 = xml_add(xml, xmlencode("3

  • Array Functions

    59

    The method supports XML namespaces in the same way as xml_new_element().

    Examples:

    var ns = xml_ns("http://www.avid.com"); var xml = "5"; // 1.) Add a child element: var modifiedXml = xml_add(xml, xml_new_element(ns + "b", "abc")); // returns: // 5abc // 2.) Add an attribute: var modifiedXml2 = xml_add(xml, xml_new_attribute(ns + "id", "1")); // returns: // 5 // 3.) Add an XML fragment: var modifiedXml3 = xml_add(xml, "xyz"); // returns: // 5xyz

    Array Functions

    SWoDL supports a number of built-in functions for arrays which are inspired by LINQ. The following built-in functions are supported:

    • array_aggregate: Aggregates the elements of an array using a given aggregation function

    • array_all: Returns true if all elements of an array fulfill a given condition

    • array_any: Returns true if any element of the array fulfills a given condition

    • array_select: Transforms the elements of an array using a given transformation function

    • array_where: Returns all elements of an array that fulfill a given condition

    Aggregating Elements: array_aggregate

    The array_aggregate function aggregates the elements of an array using a given aggregation function. The method accepts two parameters:

    • An array

  • Array Functions

    60

    • An aggregation function

    The aggregation function is a SWoDL expression that uses the special variables _a and _b.

    Examples:

    var numbers = array_create(); numbers[0] = 5; numbers[1] = 3; numbers[3] = 7; var sum = array_aggregate(numbers, (int)_a + (int)_b); // sum = 5 + 3 + 7 = 15 var product = array_aggregate(numbers, (int)_a * (int)_b); // product = 5 * 3 * 7 = 105

    The array_aggregate function works as follows:

    • If the array is empty, it returns an empty string.

    • If the array has one element, it returns that element.

    • If the array contains two or more elements, it assigns the value of the first element to _a and the value of the second element to _b. Then it executes the aggregation function and assigns the result to _a. If there are more elements, it assigns the value of the next element to _b, executes the aggregation function, and assigns the result to _a; and so on, until all entries are handled. Finally, the value of _a is returned.

    The method only uses elements that are set in the array. In the example, only the indexes 0, 1, and 3 are set, but not 2. This means that only the elements with indexes 0, 1, and 3 are aggregated.

    If there is a global variable _a or _b, the value is not visible while executing the array_aggregate function, but the values of the global variables are restored after the execution.

    Checking a Condition on all Elements: array_all

    The array_all function checks if all elements of an array meet a given condition. The method accepts two parameters:

    • An array

    • A condition function

  • Array Functions

    61

    The condition function is a SWoDL expression that uses the special variable _value and returns a boolean result value.

    Examples:

    var numbers = array_create(); numbers[0] = 5; numbers[1] = 3; numbers[3] = 7; var allAreLessThan10 = array_all(numbers, (int)_value < 10); // true, because all values are less than 10 var allAreLessThan6 = array_all(numbers, (int)_value < 6); // false, because 7 is not less than 10

    The array_all function works ad follows:

    • If the array is empty, it returns true (“1”).

    • If the array is not empty, the method iterates over all elements in the array. It assigns the value of an element to _value and evaluates the condition function. If the result for an element is false, it terminates execution and returns false (“0”). If the result is true for all elements, it returns true (“1”).

    The method only uses elements that are set in the array. In the example, only the indexes 0, 1, and 3 are set, but not 2. This means that only the elements with indexes 0, 1, and 3 are checked.

    If there is a global variable _value, the value is not visible while executing the array_all function, but the values of the global variable are restored after the execution.

    Checking if any Element Fulfills a Condition: array_any

    The array_any can be called with one or two parameters:

    • When called with one parameter, it returns true if the array is not empty.

    • When called with two parameters, it checks if any element of an array fulfills a given condition.

    The method accepts the following parameters:

    • An array

    • Optional: a condition function

  • Array Functions

    62

    The condition function is a SWoDL expression that uses the special variable _value and returns a boolean result value.

    Examples:

    var numbers = array_create(); numbers[0] = 5; numbers[1] = 3; numbers[3] = 7; var anyAtAll = array_any(numbers); // true, because the array is not empty var anyIsLessThan4 = array_any(numbers, (int)_value < 4); // true, because 3 is less than 4 var anyIsLessThan2 = array_all(numbers, (int)_value < 2); // false, because no element is less than 2

    The array_any function works like this:

    • If the array is empty, it returns false (“0”).

    • If the array is not empty and no condition function is given, it returns true (“1”).

    • If the array is not empty and a condition function is given, the method iterates over all elements in the array. It assigns the value of an element to _value and evaluates the condition function. If the result for an element is true, it terminates execution and returns true (“1”). If the result is false for all elements, it returns false (“0”).

    The method only uses elements that are set in the array. In the example, only the indexes 0, 1, and 3 are set, but not 2. This means that only the element with indexes 0, 1, and 3 are checked.

    If there is a global variable _value, the value is not visible while executing the array_any function, but the values of the global variable are restored after the execution.

    Transforming an Array: array_select

    The array_select function returns a new array that contains all elements of a given array, transformed by means of a transformation function.

    The method accepts two parameters:

    • An array

  • Array Functions

    63

    • A transformation function

    The transformation function is a SWoDL expression that uses the special variable _value.

    Example:

    var numbers = array_create(); numbers[0] = 5; numbers[2] = 7; numbers[4] = 3; var squareRoots = array_select(numbers, (int)_value * (int)_value); // returns an array with three enries: // - entry #0 contains 5 * 5 = 25 // - entry #2 contains 7 * 7 = 49 // - entry #4 contains 3 * 3 = 9

    The array_select function works as follows:

    • If the array is empty, it returns an empty array.

    • If the array is not empty, the method iterates over all elements in the array. It assigns the value of an element to _value, evaluates the transformation function and assigns the result to the resulting array. The result is a new array that contains all entries of the original array with their original index, but transformed using the transformation function.

    The method only uses elements that are set in the array. In the example, only the indexes 0, 2, and 4 are set, but not 2. This means that only the elements with indexes 0, 2, and 4 are transformed and returned.

    If there is a global variable _value, the value is not visible while executing the array_select function, but the values of the global variable are restored after the execution.

    Filtering Elements with a Condition: array_where

    The array_where function returns a new array that contains all elements of a given array that meet a given condition.

    The method accepts two parameters:

    • An array

    • A condition function

  • JSON Functions

    64

    The condition function is a SWoDL expression that uses the special variable _value and returns a boolean result value.

    Example:

    var numbers = array_create(); numbers[0] = 5; numbers[2] = 7; numbers[4] = 3; var lessThan6 = array_where(numbers, (int)_value < 6); // returns an array with two enries: // - entry #0 contains 5 // - entry #1 contains 3 // The indexes of the resulting array are consecutive integer values // starting with 0.

    The array_where function works as follows:

    • If the array is empty, it returns an empty array.

    • If the array is not empty, the method iterates over all elements in the array. It assigns the value of an element to _value and evaluates the condition function. The result is a new array that contains all elements that fulfill the given condition. The indexes of the items in the resulting array are consecutive integer values starting with 0.

    The method only uses elements that are set in the array. In the example, only the indexes 0, 2, and 4 are set, but not 2. This means that only the elements with indexes 0, 2, and 4 are checked.

    If there is a global variable _value, the value is not visible while executing the array_where function, but the values of the global variable are restored after the execution.

    JSON Functions

    Handling JSON documents is described in the following sections:

    • Parsing JSON Documents

    • Creating JSON Documents

    Parsing JSON Fragments

    You can parse JSON documents into SWoDL variables using the json_to_swodl() method.

  • JSON Functions

    65

    Example:

    var json = "[" + " {" + " \"name\" : \"John Doe\"," + " \"benefits\": [" + " \"Life Insurance\"," + " \"Disability Insurance\"" + " ]" + " }," + " {" + " \"name\" : \"Bob Smith\"," + " \"benefits\": [" + " \"Life Insurance\"," + " \"Disability Insurance\"," + " \"401K\"" + " ]" + " }" + " ]"; var employees = json_to_swodl(json); // employees[0].name -> John Doe // employees[0].benefits[0] -> Life Insurance // employees[0].benefits[1] -> Disability Insurance // employees[1].name -> Bob Smith // employees[1].benefits[0] -> Life Insurance // employees[1].benefits[1] -> Disability Insurance // employees[1].benefits[2] -> 401K

    Creating JSON Fragments

    You can create JSON documents from SWoDL variables using the swodl_to_json() method.

    Example

    var arr = array_create(); arr[0].name = "John Doe"; arr[0].benefits[0] = "Life Insurance"; arr[0].benefits[1] = "Disability Insurance"; arr[1].name = "Bob Smith"; arr[1].benefits[0] = "Life Insurance"; arr[1].benefits[1] = "Disability Insurance"; arr[1].benefits[2] = "401K"; var params; params.employees = arr; var json = swodl_to_json(params);

  • Regular Expressions

    66

    The swodl_to_json method is used to create a JSON fragment. The resulting JSON fragment looks like this:

    { "employees": [ { "name" : "John Doe", "benefits": [ "Life Insurance", "Disability Insurance" ] }, {