Composer User's Guide

CHAPTER 10

Custom Scripting and XPath Logic in exteNd Composer

Novell exteNd Composer incorporates an onboard EMCAScript interpreter, which allows you to extend the functionality of Composer applications in various ways. For example, you can use scripting to:

The XPath language also offers opportunities to exploit custom logic in your Composer components. The XPath specification includes over two dozen predefined functions that can be used to filter, qualify, aggregate, and/or locate XML data.

This chapter discusses some of the techniques and capabilities applicable to the use of custom ECMAScript and/or XPath logic in Composer and describes the relationship of various W3C standards to XPath and ECMAScript.

 
Top of page

What is ECMAScript?

ECMAScript is a lightweight, object-oriented scripting language for extending the functionality of diverse host environments (such as web browsers, editors, and IDEs) by enabling the use of custom logic. It is designed to complement or extend existing functionality in a host program such as exteNd Composer. In the web-browser world, ECMAScript is often called JavaScript or JScript.

ECMAScript is especially appropriate for a Java host environment, since:

The extensibility of ECMAScript, its powerful string-handling tools (including regular expressions), its DOM binding, and its ability to provide a bridge to Java, make it an ideal language to augment the programming constructs and standards used by exteNd Composer.

NOTE:   You can find detailed information regarding ECMAScript at the European Computer Manufacturers Association (ECMA) web site: http://www.ecma.ch/

 
Top of page

What Capabilities Does ECMAScript Offer?

In addition to letting you incorporate finely tuned custom logic into your Action Model, scripting gives you a great deal of flexibility in manipulating data, because of the various DOM- and XPath-related objects and methods available in Composer's ECMAScript extensions. Also, as an extensible language, custom user-defined objects can be created on-the-fly in ECMAScript and used in your Composer components and services.

The usefulness of ECMAScript is especially apparent when dealing with in-memory DOMs. Composer constructs XML documents as in-memory objects according to the W3C DOM Level 2 specification. The DOM-2 specification, in turn, defines an ECMAScript binding (see http://www.w3.org/TR/DOM-Level-2-Core/ecma-script-binding.html), with numerous methods and properties that provide ready access to DOM-tree contents. The standard Composer DOMs—Input, Input1, Input(n), Temp, and Output—are objects recognized by ECMAScript in Composer, and any of the W3C-defined ECMAScript extensions that apply to DOMs can be accessed from Composer.

ECMAScript also provides bridges to other expression languages such as XPath. In Composer's case, this allows you to use the Novell-supplied method XPath() on a DOM to address various elements within its document structure.

Another useful aspect of Composer's ECMAScript binding is its inclusion of file-I/O extensions (which are not a part of the core language). Using custom scripts, you can easily read or write scratch files, persist information to disk, or perform other common file-access tasks.

Composer's ECMAScript binding also includes database extensions that permit programmatic access to databases via JDBC. SQL statements can be passed as strings and executed against any database to which a connection can be defined.

 
Top of page

How Scripting Is Exposed in Composer's User Interface

Composer offers access to ECMAScript in many parts of the component editor user interface, as described throughout this Guide. The most common form of access is through the Expression Builder, which can be entered whenever you see this icon:

10ExpressionEditorIcon

This icon can be found in many Composer dialogs, such as the Map Action dialog, Connection Resource dialogs, etc. If you click this icon, you bring up a dialog similar to the following.

10ExprBuilder

The Expression Builder dialog provides pick-lists of available objects, methods, and properties in the top panes (all of which are resizable), with rollover tool tips to help you build ECMAScript statements. Doubleclicking any item in any picktree will cause a corresponding ECMAScript statement to appear in the small edit pane in the lower portion of the window. In the example shown above, the DOM picktree corresponding to PROJECT has been opened in the Variables pane, and the node at

  USERCONFIG/PROJECT_CONFIG/DESIGNER_EMULATION_MODE 

has been doubleclicked. The ECMAScript expression that can access the contents of this node in the PROJECT DOM appears automatically in the edit pane.

In the window's button bar, there is a Validate button. Clicking this button will result in the ECMAScript interpreter syntax-checking your expression(s) in real time. If there are problems involving ECMAScript syntax, you will see an error dialog immediately. You can then edit the expression(s) and revalidate as needed. (Validation is, however, optional.)

NOTE:   The Validate process does not execute your expression(s). It merely checks syntax.

Expressions for Dynamic Parameter Values

Each Composer action typically requires one or more parameters needed to perform the action. Wherever possible, Composer allows you to substitute ECMAScript expressions for these parameters. You can enter a static string, or an expression, or a series of expressions separated by semicolons. Since expressions are evaluated at runtime, this enables you to defer the choice of a parameter value until execution. This kind of late binding of parameter values is essential in cases where input values simply aren't known in advance.

Example: You might choose to hard -code a static string value for a Send Mail action's Recipient parameter. But you could also use ECMAScript to construct an e-mail address from data inside an incoming XML document, creating a flexible data-driven action with the ability to provide customization based on runtime knowledge.

Most of Composer's actions accept ECMAScript expressions for parameter values. In most cases, an XPath expression is also accepted. You will usually be able to choose from two radio buttons, labelled "XPath" and "Expression." To access the ECMAScript Expression Builder, choose the Expression radio button and click the small Expression Builder icon next to the text field where the parameter value should appear.

Custom Script Libraries

ECMAScript is also integrated into Composer as a general resource called Custom Scripts. The Custom Script resource provides an editing environment for creating custom ECMAScript functions, which you can run and debug with a command-line evaluator right inside the editor. The script editor also provides access to sample XML documents (DOM trees) and has a Java class browser so that you can easily write scripts that bridge to custom Java code. You can save libraries of custom scripts as Custom Script resources and see them listed in the instance pane of Composer's navigation frame. Also, when you've assembled custom functions into a Custom Script Resource, they automatically appear in all Expression Builder dialog pick-lists.

See "About XSD Resources" on page 261 for more detailed information about Custom Script resources and the script editor.

Function Actions

Another way in which ECMAScript functionality is exposed in Composer is through the Function Action, which is one of the core actions available in all component editors. You can insert a Function Action anywhere in your action model, to initialize variables, call custom functions, etc. One of the handiest uses of the Function Action is as a debugging aid. You can call the built-in alert() function with any string argument (the content of a DOM node, for example) in order to inspect the contents of a parameter value before and after an action or block of actions. The alert() function will bring up a dialog showing the string.

NOTE:   For obvious reasons, you should disable alert() calls prior to deployment. This is strictly a design-time method with no applicability to the server environment.

See "The Function Action" on page 139 for information on how to create and use Function actions.

 
Top of page

ECMAScript Access from XPath

Some dialog fields require an XPath expression. But in some instances, you may find that you prefer the greater expressivity of ECMAScript over XPath, or your logic requirements may not be accommodated by XPath's relatively limited set of built-in functions. In cases of this sort, you can still use ECMAScript: Access to ECMAScript is available, in any field requiring XPath, via the userfunc namespace.

For example, let's say you've defined your own custom ECMAScript function called getTotal():

  function getTotal(a,b) {
      return Number(a) + Number(b);
  }

You could define this function either in a Custom Script resource in your project, or inside a Function Action.

Suppose you want to call this function from an XPath statement, passing (as arguments) values stored in two DOM nodes given by ORDER/SUBTOTAL and ORDER/TAX. Here is how you would write the XPath:

  userfunc:getTotal(ORDER/SUBTOTAL,ORDER/TAX)

Here is how this call might look in an XML Map Action dialog:

10userfunc

 
Top of page

XPath Access from ECMAScript

Just as you can reach ECMAScript functions from XPath, you can also obtain node objects, node data values, etc.via ECMAScript. Composer offers a variety of ECMAScript extensions for manipulating DOM elements (discussed further below). Probably the most often-used of these extensions is the XPath() method, which takes an XPath-style path string as the sole argument:

  var taxNode = Input.XPath("ORDER/TAX");
  var taxAmt = taxNode.toString() * 1;

Notice that the XPath() method, which is parented off a DOM root (in this case, Input), always returns a node object, not the node's value. To obtain the node's data value, apply the core-language ECMAScript method toString() to it. If the resulting string value will be used as a number, cast it to a number either by wrapping it in ECMAScript's Number() constructor or by multiplying by one (as shown).

NOTE:   The most common error when using the XPath() method is to assume that it returns a data value (string, number, etc.), when in fact it returns a or node list. Use item(0).toString() to obtain the data value from the first node object in the returned node list.

 
Top of page

Scope of Custom Script Functions and Variables

Functions stored in Custom Script resources are available to any component or service in your project, at any point in any action model. (Note, however, that after you've written a custom function, the associated Custom Script resource must be Saved before the function is available to a component.)

Global variables within Custom Script resources (that is, variables declared outside of custom functions) are visible only to Custom Script resource functions that use the variable(s). In other words, if you declare a variable, myVariable, inside a Custom Resource called myFunctions, only the functions within myFunctions will be able to see and use myVariable.

Variables declared within a component's action model are scoped to the component. That is, a variable declared at the top of an action model (in a Function Action) is visible to any action downstream of the declaration, and lives for the lifetime of the component, but that variable is not available to external components.

To achieve inter-service scope of variables, use the putSessionValue() and getSessionValue() methods described further below, in the section titled "Component (xObject)" on page 281.

 
Top of page

Looking at an ECMAScript Example

Inside the body of any custom function, you can treat a DOM as an ECMAScript object and call valid methods on the object—such as toString(), which writes the DOM out to a string as text.

NOTE:   In addition to custom functions, all of the standard built-in ECMAScript objects (Array, Boolean, Date, Function, Math, Object, Number, RegExp, String, and the top-level Global object), and their associated methods and properties, can be accessed from your expressions.

An example of a custom ECMAScript expression that you might use in a Function action is:

  var onHand = Input.XPath("INVENTORYSTATUS/ONHAND");
  if (Number(onHand) < 10)
     Output.XPath("PRODUCTRESPONSE/INVENTORYSTATUS") =
  	         "Time to reorder";

This script says to check the value in the Input DOM at the INVENTORYSTATUS/ONHAND element node, and if it is less than 10, map the string "Time to reorder" to the Output DOM at element PRODUCTRESPONSE/INVENTORYSTATUS.

Note that in accordance with ECMAScript syntax rules, no data-type label need be included in the declaration of the local variable onHand. The value retrieved in onHand is likely to be a string, however. To cast it to a number, we apply the core ECMAScript Number() function to it. This permits us to use the less-than operator inside the conditional.

It's entirely possible, of course, that onHand might end up being assigned a value (such as an empty string) that cannot be cast to a number, in which case Number() will return the problematic value NaN, which will then cause our conditional to generate an exception. In order to handle this possibility without generating the exception, one could do:

  if ( !isNaN(Number(onHand) ) ) ?
      if (Number(onHand) < 10)
          [ code here ]

The isNaN() method is a core ECMAScript-language method which checks for "numberness."

As an alternative to the isNaN() tactic, one could wrap the example code in a try/catch statement and handle any exception in the catch block. (The try/catch construct is supported by ECMAScript.)

NOTE:   For more ECMAScript examples, open (or import into your project) any of the Custom Script resources included in the sample Composer project called "Expressions."

 
Top of page

Performance Considerations

ECMAScript is an interpreted language, which means that every line of script in an expression must be parsed and translated to the Java equivalent before it can be executed. This adds considerable overhead to the code and results in overall slower execution of scripts than pure Java. Before using ECMAScript extensively in your components and services, you should think about the possible performance ramifications.

The following guidelines will help you achieve optimal performance in your components and services:

Bear in mind that the key to good performance is always a good implementation: choosing the correct algorithm, attention to reuse of variables, etc. Good code written in a slow language will often outperform bad code written in a fast language. Writing something in Java does not guarantee that it will be faster than the equivalent logic written in ECMAScript, because Java has its own overhead constraints involving, for example, constructor call-chains. (When you call a constructor for a Java object that inherits from other objects, the constructors for all ancestral objects are also called.)

ECMAScript's core objects (String, Array, Date, etc.) have many built-in convenience methods for data manipulation, formatting, parsing, sorting, interconversion of strings and arrays, etc. These methods are implemented in highly optimized Java code inside the interpreter. It is to your advantage to use these methods whenever possible, rather than "roll your own" data-parsing or formatting functions. For example, suppose you want to break a long string into substrings, based on the occurrence of a delimiter. You could create a loop that uses the String methods indexOf() and substring() to parse out the substrings and assign them to slots in an array. But this would be a very inefficient technique when you could simply do:

  var myArrayOfSubstrings = bigString.split( delimiter );

The ECMAScript String method split() breaks a string into an array of substrings based on whatever delimiter value you supply. It executes in native Java and requires the interpreter to interpret only one line of script. Trying to do the same thing with a loop that iteratively calls indexOf() and substring() would involve a great deal of needless interpreter and function-call overhead, with the attendant performance hit.

Skillful use of built-in ECMAScript methods will pay worthwhile performance dividends. If you will be using scripts extensively, take time to learn about the fine points of the ECMAScript language, because this can help you eliminate performance bottlenecks.

 
Top of page

What Is XPath?

XPath is the W3C standard that describes a syntax for addressing or locating content within an XML document. XPath also provides a lightweight expression language for manipulation of strings, numbers and booleans, so that users can exercise fine control over the harvesting and aggregation of XML data.

XPath models an XML document as a tree of nodes with parents and children. The nodes include element nodes, attribute nodes and text nodes. XPath uses an addressing scheme that resembles the directory/file path-specification conventions of some file systems, in that a slash separates parents from children. The following familiar constructs apply:

An XPath address is often called an expression and is evaluated in reference to a context. A context in Composer is usually a DOM such as Input, Input1, Input(n), Temp or Output. A context in Composer can also be a Group name which itself is simply an alias or shorthand for an XPath expression.

 
Top of section

Who Is the Target Audience for XPath?

XPath is intended to be used by all users of Composer for almost all tasks needed in processing XML documents. In some cases, as a programmer, you may find XPath insufficient in its addressing capabilities. In these cases, you may choose instead to use the more granular DOM methods, (described in About DOMs) for addressing an XML document. If XPath and DOM both prove inadequate then you can always choose to process an XML document directly with a Java program.

 
Top of section

When Would I Want to Use XPath?

You can use XPath expressions whenever you want to reference an element (or attribute) or group of elements (attributes) in an XML document. In particular, you will use XPath expressions frequently in Map actions in order to specify inputs and outputs for data transfer between XML documents. You will also use XPath in Group declarations (which create a list of tree nodes matching an XPath expression) and Repeat for Element actions, which create an alias name for a repeating pattern of elements in a document.

You can also use XPath expressions in the custom ECMAScript expressions you create. Composer provides a special bridge method called XPath() that allows you to use XPath expressions within ECMAScript functions. A typical syntax is:

  Input.XPath("ROOT/PARENT/CHILD")

Notice that the XPath() method is parented off the DOM object, which in this example is named Input. Also notice that the argument to XPath() is a string. (It can be either a literal, static string, or a string variable.)

 
Top of section

How Is XPath Integrated into Composer?

XPath is the fundamental addressing mechanism in Composer. It is integrated directly into Composer via the dialogs for such actions as Map, Repeat for Element, and Group (plus many others). In these actions, an XPath is specified as two parts: a context and an expression. The XPath context represents the "base address," relative to which evaluation of the rest of the expression should occur. In most cases this is simply the name of a DOM (Input, Input1, Temp, Output, etc.), which represents the root in an XML document (i.e., the Document object).

The expression part of an XPath specifies, in top-down order, the chain of elements that leads to the node (or list of nodes) to be processed.

An XPath is created in Composer automatically by Map actions created via drag and drop. You can specify XPath expressions yourself in Map Action dialogs using the XPath Expression Builder, which provides pick-lists of valid XPath statements. You can access the XPath expression builder by pressing the Expression Builder button (shown below) whenever the XPath radio button is selected in a dialog.

Composer integrates XPath with ECMAScript by the special method .XPath(). This allows you to address parts of an XML document using XPath syntax within the ECMAScript language.

Composer also provides the concept of groups in conjunction with XPath. When you declare a group name, it is associated with an XPath pattern that occurs multiple times in a document. This results in two special lists of nodes in the tree. The first list is a Group containing one entry for each unique node value found in the XML document based on the pattern. You can then set up a Repeat for Group loop that processes actions once for each group.

The second list is a Group(Detail) containing one entry for each member of each group (unique or not). You can then set up a Repeat for Group loop that processes actions once for each group member

 
Top of section

Looking at an XPath Example

XPath in the Map Action

XpathinMapAction

In the above example, the context is the "Input" DOM. The XPath expression is INVOICEBATCH/INVOICE/INVOICEHEAD/INVOICENO, specifying the element location of INVOICE NO as a child of INVOICEHEAD, which is a child of INVOICE, which is a child of INVOICEBATCH.

XPath in ECMAScript

XpathinECMAScript

In the above example, the context is the XML document object "Input1" which uses the method ".XPath( )" to specify a location of INVENTORY_STATUS/SKU and convert it to a text string (source XML). This text string object can then be manipulated using ECMAScript methods.

XPath in Groups

10DeclareGroup

In the above example, the group name "srgSELLERNAME," creates a list of nodes based on the unique data values in the XPath "$Input/INVOICEBATCH/INVOICE/SELLERNAME." This list of unique nodes can then be processed by a Repeat for Group loop action to map data based on the unique group values instead of the individual values of each member of each group.

 
Top of page

XPath Functions

By way of augmenting XPath's literal-addressing capabilities, XPath's designers built an expression language into the specification, to allow sophisticated filtering, introspection, and aggregation of node sets. XPath, in fact, predefines more than two dozen convenience functions (see Table ) that natively recognize four data types: string, number, boolean, and node-set. The use of these functions in conjunction with ordinary XPath addressing gives the XML developer a powerful tool for manipulating XML data.

Note that all of these functions are exposed in Composer's Expression Builders, complete with rollover (tooltip) help.

XPath Functions

Node-Set Functions

number last()

number position()

number count(node-set)

node-set id(object)

string local-name(node-set)

string namespace-uri(node-set)

String Functions

string name(node-set)

string string(object)

string concat(string, string, string*)

boolean starts-with(string, string)

boolean contains(string, string)

string substring-before(string, string)

string substring-after(string, string)

string substring(string, number, number)

number string-length(string)

string translate(string, string, string)

Boolean Functions

boolean boolean(object)

boolean not(boolean)

boolean true()

boolean false()

boolean lang(string

Number Functions

number number(object)

number sum(node-set) .

number floor(number)

number ceiling(number)

number round(number)

While a detailed discussion of the use of XPath functions is beyond the scope of this Guide (see instead the complete XPath specification at http://www.w3.org/TR/xpath), a few quick examples will illustrate the power and elegance of the XPath expression language:

XPath Expression

Meaning

//*

The node set consisting of all nodes in the document

count(//*)

The number of nodes in the document

count(//*[contains(name(),'myNode')])

The number of nodes in the document whose name contains the (sub)string "myNode"

name(//*)

From the set of all nodes, find the name of the first node of the document, in document order. (That is, find the root node's name.)

//*[name()='myNode']/@*

Starting with the set of all nodes, find a node whose name is "myNode" and obtain the value of the first attribute under that node, in node order.

name(//*[name()='myNode']/@*)

Obtain the name of the first attribute node found in the node `myNode'

concat(//*[name()='myNode4']/@*,' is what was found')

Combine the value stored in the first attribute that occurs under the element "myNode4" with the string " is what was found".

For more XPath examples, see the "Action Examples" project that ships with Composer.

 
Top of section

Documentation Resources for XPath

 
Top of page

About XSL

The following section describes writing custom scripts that use XSL .

 
Top of section

What is XSL?

Extensible Stylesheet Language is a language for transforming XML documents into other kinds of documents.As a stylesheet language, XSL includes an XML vocabulary for specifying formatting.

Unlike HTML, element names in XML have no intrinsic presentation semantics. Without a stylesheet, an XML delivery process has no way of knowing how to render the content of an XML document other than as an undifferentiated string of characters. XSL provides a comprehensive model and a vocabulary for writing understandable stylesheets using an XML syntax.

The functionality of XSL is augmented by XSLT (XSL Transformations), which is a non-presentation-oriented transformation language for manipulating XML structure. XSLT makes use of the expression language defined by XPath for selecting elements for filtering, conditional processing, and generating string values either supplied from a source XML document or by the stylesheet author.

 
Top of section

Who is the Target Audience for XSL?

Users who are interested in XSL are webmasters, eCommerce site builders, portal builders, and anyone else in need of a graphical representation of XML documents as part of business-to-business transactions.

Given an XML document, designers can use an XSL stylesheet to express how that structured content should be presented; in other words, how the source content should be styled, laid out, and/or paginated onto some presentation medium, such as a window in a Web browser or a hand-held device, or a set of physical pages in a catalog, report, pamphlet, or book.

 
Top of section

When Would I want to Use XSL?

XSL is designed to permit XML delivery devices to display XML in a way that is meaningful to humans. XML data exchanges often involve user interactions—Web shopping experiences, data auditing, notifications, and other XML uses requiring a graphical display of data. In short, you would use XSL whenever you need to make XML presentation-enabled.

 
Top of section

How is XSL Integrated into Composer?

XSL is integrated into Composer by means of the XSL Transform Action, which is available in all components. To use the action, you need to specify parameters for a source DOM, an XSL Stylesheet, and a destination DOM (e.g., Temp or Output). See the next section for an illustration.

Composer also provides special XSL methods for use in Custom Scripts or Function Actions:

  transformNodeViaDOM() 
  transformNodeToObject(,)
  transformNodeViaXSLURL()

See the API descriptions further below for details on these methods.

Web services that you create using exteNd can also be set up to output XSL-transformed XML directly as HTML. See the Deployment chapter in the exteNd Composer Enterprise Server Guide for your particular app server platform for more information on deployment to HTML using Processing Instructions.

 
Top of section

Looking at an XSL Example

The Process XSL action shown below uses the XSL stylesheet specified in the XSL URL field to transform the input Part, placing the result into an XML element called "MyHTML" in the output doc.

10ProcessXSL

For additional examples of how to use XSL, be sure to see the "Action Examples" project in your Composer installation.

 
Top of section

Resources for XSL

 
Top of page

About Novell Scripting Extensions

The Novell extensions to ECMAScript consist of a set of convenience methods for general purpose scripting involving xObjects, DOMs, and other Composer objects. All of the methods are exposed in the Expression Builder pick-lists. An introduction to the API is given below.

General Purpose Extensions

The general purpose extensions are categorized by the type of objects they operate on and consist of the following:

Node

XML—This property returns a string representing the DOM.

createXPath(XPathType asPattern)—Creates the XPath pattern.

getXML ()—This property returns a string representing the DOM.

Document

text—This property returns a concatenated string of all the text nodes (content) under it.

setDTD(node RootElementName, object PublicName, object URL)—Sets DTD file for the document.

setValue(Object aValue)—Sets the Value of a Document from the passed object, if it is in another document, then this method copies child nodes (elements and attributes). If passed object is text, it is parsed to create a DOM.

toString()—Converts a DOM document to an XML formatted string.

transformNodeViaDOM(XSLDOM)—Transforms the document according to the XSLDOM and returns a string. The parameter XSLDOM is an XSL stylesheet, that may have been read into the component by an XML Interchange Action. This method could be used in the source of a Map Action, or call it in a Servlet using the Server Framework class IGXSXSLProcessor.

transformNodeToObject(XSLDOM, OutputDOM)—Transforms the document according to the XSLDOM and returns results to Output DOM. The parameter XSLDOM is an XSL stylesheet that may have been read into the component by an XML Interchange Action. The parameter Output DOM is the target DOM for the results. From a component, this method could be in a Function Action, or from a Custom Script, you can use it once you have all three DOMs, or call it in a Servlet, using the Server Framework class IGXSXSLProcessor.

transformNodeViaXSLURL(XSLURLLocation)—Transforms the document according to the XSLURLLocation and returns a string. The parameter XSLURLLocation is an XSL stylesheet. This method could be used in the Source of a Map Action, or from a Custom Script you can use it once you have a DOM, or call it in a Servlet using the Server Framework class IGXSXSLProcessor.

validate()—XPathTypes can be of type NodeList, String, Number, or Boolean. Usually used to return a Nodelist matching the XPath pattern. Use brackets to select a particular node from the list [e.g.,.Input.XPath("INVOICE/LINEITEM[1]") or Input.XPath("INVOICE/LINEITEM[last()]")]. Use the @ to select a node by attribute (e.g. Input.XPath("INVOICE/LINEITEM[@myattr]"). To select by attribute value...Input.XPath("INVOICE/LINEITEM[@myattr='abc']").

Nodelist XPath(XPathType asPattern)—XPathTypes can be of type NodeList, String, Number, or Boolean. Usually used to return a Nodelist matching the XPath pattern. Use brackets to select a particular node from the list [e.g.,Input.XPath("INVOICE/LINEITEM[1]") or Input.XPath("INVOICE/LINEITEM[last()]")]. Use the @ to select a node by attribute [e.g. Input.XPath("INVOICE/LINEITEM[@myattr]")] To select by attribute value...Input.XPath("INVOICE/LINEITEM[@myattr='abc']").

Element

text—This property returns the concatenated text of all the text nodes under it.

booleanValue()—Returns the boolean value (true | false) of this object if possible.

countOfElement(String propertyName)—Returns a count of the named child.

doubleValue()—Returns a double value for this object if possible.

exists(String propertyName)—Check for the existence of the named child.

getIndex()—Returns back the current index.

getParent()—Returns the parent element.

setIndex(int aiIndex)—Sets the iterator index value for this element.

setText(String asText)—Sets the text node associated with this element.

setValue(Object aValue)—Sets the Value of an Element from the passed object, if it is another element then this method copies child nodes also (elements and attributes).

toNumber()—Gets the text node and converts it to a number.

toString()—Gets the text node associated with this element.

Nodelist XPath(XPathType asPattern)—XPathTypes can be of type NodeList, String, Number, or Boolean. Usually used to return a Nodelist matching the XPath pattern. Use brackets to select a particular node from the list, e.g., Input.XPath("INVOICE/LINEITEM[1]") or\nInput.XPath("INVOICE/LINEITEM[last()]"). Use the @ to select a node by attribute, e.g., Input.XPath("INVOICE/LINEITEM[@myattr]") To select by attribute value...\nInput.XPath("INVOICE/LINEITEM[@myattr='abc']").

Attribute

text—This property returns the text value of the attribute.

setValue(Object aValue)—Sets the Value of an Attribute from the passed object.

toString()—Gets the text node associated with this attribute.

Nodelist

avg(NodeList)—Returns a number equal to the average value in the NodeList. The NodeList parameter of type XPath. If no parameter is supplied, then the current NodeList/GroupName is used.

count([NodeList])—Returns a number equal to a count of the nodes in the NodeList. The optional NodeList parameter is of type XPath. If no parameter is supplied (the usual case), then the current NodeList/GroupName is used.

min([NodeList])—Returns a number equal to the lowest value in the NodeList. The NodeList parameter of type XPath. If no parameter is supplied, then the current NodeList/GroupName is used.

max([NodeList])—Returns a number equal to the highest value in the NodeList. The NodeList parameter of type XPath. If no parameter is supplied, then the current NodeList/GroupName is used.

sum([NodeList])—Returns a number equal to the sum of the values in NodeList. The NodeList parameter of type XPath. If no parameter is supplied, then the current NodeList/GroupName is used.

where(XPathType asPattern)—Gets a NodeList of nodes matching the XPath pattern.

Component (xObject)

An object called theComponent is exposed within each Composer component via the Expression Builder. (You can open the Expression Builder window by clicking the Expression icon in any Function action, Map action, or other dialog in which the icon appears.) The component-based methods are exposed in the pick-list under Extended ECMAScript/Component, as shown below.

10ComponentMethods

The object called Component has the following methods:

getName()—Returns the name of the currently executing component. To obtain the name of the currently executing component, you would call:

  Component.getName()

exportObject(key,value)—Allows you to store a reference to any ECMAScript variable or Java object in a hash table so that other components within a given service can look up the object and use it. (Otherwise, user variables are scoped to the component in which they are declared and cannot be seen by other components.) For example, suppose you have created a variable, testString, and you wish to make it available to other components in the same service:

  // create an instance of the string:
  testString = 'hello';
  
  // now export it:
  theComponent.exportObject("myExport", testString)

Note that the hash key "myExport" is simply any arbitrary name. Other components will need to use this name to look up the exported object (testString). Within another component, you can do:

var copyOfString = theComponent.getExportValue("myExport");

The component that executes this code will then have access to the string 'hello' that was in the variable testString within the other component.

It is important to understand that variables or objects exported in this fashion are scoped to the service instance in which they are created. This means:

NOTE:   To achieve inter-service scope of session variables, use the putSessionValue() and getSessionValue() methods described further below.

It is also important to understand that at design time, exported variables will not be in scope (will not be usable) unless the service or component that created them is itself running. Suppose Service A creates a variable myVar and exports it as 'myExportedVariable'. Service A calls (executes) Component B. Inside Component B is a Function Action that looks up the exported variable:

theVar = theComponent.getExportValue('myExportedVariable')

In order for theVar to contain the correct value, Service A must already be running and it must already have exported myVar. In other words, if you merely animate Component B without running Service A, you'll encounter a problem since myVar is not in scope. The correct thing to do is to begin your animation from Service A. Step through Service A until you reach the Component Action that executes Component B. Use the Step Into button to step into the action model for Component B. Then step through Component B. This way, both A and B are in scope at the same time and any exported variables will be usable.

getExportValue(key)—Allows you to access a reference to any ECMAScript variable or Java object that was previously exported by another component. (See discussion above.)

putSessionValue(key,value)—Allows you to store a reference to a Java object in a global variable so that it can be referenced from any other service or component running in the same servlet session (which may span many HTTP hits). Objects published in this fashion have servlet-level scope. (Session life is dependent on the HTTP Server Session timeouts.) The first argument is a String representing the name for the published object. The first argument is a String representing the name you wish to associated with the published object. The second argument is the object. (The syntax follows the convention for exportObject, shown above.)

NOTE:   This method will generate an exception if it is used in a Web Service that was deployed using an EJB. Also, this method cannot be used in a JMS Service.

getSessionValue(key)—Allows you to obtain a reference to a Java object that was previously published via the putSessionValue() method (above). This method will return null if no object matching the key is found; otherwise, it returns an Object.

NOTE:   This method will generate an exception if it is used in a Web Service that was deployed using an EJB. Also, this method cannot be used in a JMS Service.

removeSessionValue(key)—Allows you to destroy a reference to a Java object that was previously published via the putSessionValue() method (above).

NOTE:   This method will generate an exception if it is used in a Web Service that was deployed using an EJB. Also, this method cannot be used in a JMS Service.

LDAP Methods

getLDAPAttr(String connResource, String dn, String attr)—Looks up a value stored in a particular attribute of a named object in an LDAP directory, using the connection resource whose name is supplied in the first argument. The second argument is the object's LDAP distinguished name. The third arg is the attribute of interest. The value returned may be numeric or String data. Use ECMAScript's typeof operator to determine if the value is of type "number" versus type "string."

The getLDAPAttr() method is available for use in any component, service, or connection resource, whenever ECMAScript can be used. (In other words, its use is not limited to LDAP Components.) Other ECMAScript extension methods involving LDAP are available only within the LDAP Component editor. See the separate LDAP Connect User's Guide for more information on those methods.

Connector-Specific Extensions

Additional custom ECMAScript objects and methods beyond those described here are available in conjunction with most Connect products for exteNd. (For example, JMS-specific methods are available for use in components and services created using the JMS Connector.)

Consult the appropriate Connect documentation for details about connector-specific ECMAScript objects and methods.

 
Top of section

When Would I Want to Use Novell Scripting Extensions?

Use Composer's general purpose extensions wherever you find them helpful and /or where they are more robust than similar methods in XPath, DOM or XSL.

You might want to use some of Composer's grouping or aggregation-related extensions when you want to summarize common data that repeats but is scattered about an XML file. For instance, an XML file may arrive with 50 randomly organized invoices, generated by only seven departments in your organization. Using Composer's grouping capability and group-oriented methods, you can easily organize the 50 invoices by the departments and summarize "invoice totals" across each group.

 
Top of section

How Are Novell Scripting Extensions Integrated into Composer?

The general purpose extensions are built right into ECMAScript and appear on the Expression builder pick-lists alongside other objects, properties and methods.

Composer's Group action is used to specify Groups by simply clicking a pick-list to generate an XPath pattern that forms the basis for the group. There is a Repeat for Group Action that allows you to process a set of actions for each member of the Group or Group(Detail). The aggregate calculation methods are available in the ECMAScript Expression Builder in the Map dialog.

The types of actions described here are available in all Connect component types.

 
Top of section

Extension Code Examples

See the "Action Examples" project in the \Samples directory of your exteNd Composer installation for examples of how to use ECMAScript in Composer to accomplish a wide variety of tasks.

 
Top of page

About DOMs

 
Top of section

What is DOM?

The Document Object Model is an interface that allows programs and scripts to dynamically access and update the content, structure and style of XML documents. W3C's Document Object Model (DOM) is a standard internal representation of an XML document structure inside a software program and aims to make it easy for programmers to access elements, attributes and data and delete, add or edit their content and style.

 
Top of section

What Does a DOM Do? What are the Key Features?

The DOM defines a set of standard methods and properties for creating and operating on XML documents programmatically as objects. It provides methods for manipulating all parts of an XML document including Elements, Attributes, Text, Processing Instructions, etc.

The DOM also provides a set of methods for addressing or locating nodes in an XML document.

 
Top of section

Who is the Target Audience for DOM Methods?

The DOM methods and programming model is targeted at professional developers who need absolute control over DOM manipulation. Working with DOM methods gives developers control over primitive operations involved in constructing and manipulating DOMs. A simple Map action in Composer might translate to tens of lines of ECMAScript/DOM instructions.

 
Top of section

When Would I Want to Use DOM Methods?

You may wish to use DOM methods when the basic Composer actions combined with ECMAScript functionality cannot meet your XML document processing needs.

 
Top of section

How Are DOM Methods Integrated into Composer?

The methods and properties of the DOM for manipulating Composer DOMs are available only in the Custom Script editor or ECMAScript expression builder in Actions. You can access the ECMAScript Expression builder by pressing the expression builder button (shown below) whenever the Expression radio button is selected in a dialog.

10ExpressionBuilderButton

 
Top of section

Looking at a DOM Methods Example

 
Top of section

Documentation Resources for DOMS

 
Top of page

About Java Integration

Java is more than merely a programming language. It's a computing platform designed to allow the same software to run on different kinds of devices: PCs, Unix workstations, wireless devices, handheld computers, consumer electronics, and embedded systems of various kinds. Using networks, it is possible to create distributed applications using Java that tie together diverse devices into a single working application.

In addition to being a computing platform in its own right, Java is a robust, object-oriented computer language that forms the basis of the Java 2 Enterprise Edition (J2EE) computing architecture, which is increasingly preferred by IT organizations because of its adaptability, robustness, platform neutrality, and track record of successful adoption by large companies. J2EE is also firmly connected to emerging standards in the areas of XML and Web Services, which makes Java an ideal enterprise-programming language.

 
Top of section

How Is Java Accessible in exteNd Composer?

Java is integrated into Composer services through the ECMAScript scripting environment, which provides a direct bridge to external Java objects. Composer provides a Java class browser in the Custom Script editor with drag-and-drop functionality, enabling you to quickly integrate Java objects and use their constructors, properties, and methods within your scripts.

 
Top of section

When Should You Use Java?

Most Composer users will be able to achieve their Web Services and XML integration objectives without needing to augment Composer's native functionality through the use of custom Java classes. Nevertheless, there are situations where it may be desirable to integrate Java objects into exteNd. For example:

 
Top of section

Looking at a Java Integration Example

A simple use of Java in an XML application may be to perform a case-insensitive comparison of data in two XML elements. In this case, you could create a Custom Script function using the Java string object as follows:

  // Case Insensitive Compare, returns 0 if strings are equal, non-zero if not...
  function nonCaseCompare(string1,string2)
  {
  var s1 = new Packages.java.lang.String(string1);
  var s2 = new Packages.java.lang.String(string2);
  return s1.compareToIgnoreCase(s2);
  }

Then you might use the function in a Decision action to conditionally execute different actions, as the illustration shows.

10JavaExampleCaseCompare

 
Top of section

Documentation Resources for Java

You can find detailed and definitive information regarding the Java platform and the Java programming language at the following Web site: http://java.sun.com.




Copyright © 2004 Novell, Inc. All rights reserved. Copyright © 1997, 1998, 1999, 2000, 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved.  more ...