A Few Things to Remember About XML Maps and Script

As you work with XML maps, you might find it useful to keep in mind these notes about special behavior in XML maps and ECMAScript for mapping.

# When Using Script

## Reserved Words Require Special Handling

XML allows a great deal of flexibility when naming elements, attributes, and the like. As a result there may be times when a name in XML you are handling with script is the same as an ECMAScript keyword or one of the functions provided for use with XML. When elements have names that conflict with ECMAScript keywords or function names, you can use the following syntax instead. Note that there are two different workarounds — one is for use with ECMAScript keywords and the other is for use with function names. The following example illustrates the workaround for the . operator; be sure to see the documentation for the specific operator you are trying to use.

    /*
     * Return all of the <if> elements.
     * This avoids a conflict with the "if" ECMAScript keyword.
     */
    var ifs = xmlData.product_description["if"];
    /*
     * Return the first <parent> element.
     * This avoids a conflict with the parent function.
     */
    var firstParent = xmlFamilies.kid.::parent[0];

## XML Fragments Must Have an Anonymous Root

The XML-related data types included with Workshop's extended ECMAScript allow you to assign XML fragments to XML variables. However, a fragment must be enclosed in an anonymous element represented by <> and </>, as in the following example:

    var myXMLList =
    <>
        <firstname>John</firstname>
        <lastname>Walton</lastname>
        <age>25</age>
    <>

# When Using Maps

## Function References in XML Maps Must Be a Root Element

The function reference (everything between and including the curly braces) must be the only child of its parent element. For example, the following XML map fragment will cause an error:

    <placeOrder xmlns="http://www.openuri.org/">
        {CustomerServices.OrderScripts.convertOrder(currentOrder, currentCustomer)}
        <customer_info>{currentCustomer}</customer_info>
    </placeOrder>

But something like the following would work:

    <placeOrder xmlns="http://www.openuri.org/">
        <order_info>
            {CustomerServices.OrderScripts.convertOrder(currentOrder, currentCustomer)}
        </order_info>
        <customer_id>{currentCustomer.custID}</customer_id>
    </placeOrder>

For more information, see How Do I: Use Script from a Web Service?

## Literal Text Can't Be Combined with Substitutions

Literal text — that is, text that is not part of an XML element or attribute name and is not part of mapping tags and attributes — is allowed in XML maps only under certain circumstances. For example, literal text may not be combined with substitution directives (text in xm tags or between curly braces), as in the following example:

    <!-- not a legal xml map -->
    <item>
        <description>  bad text  {d}  bad text
        </description>
        bad text
        <quantity units="bad text {u} bad text">
            bad text  {q}  bad text
        </quantity>
        bad text
    </item>

The following example, however, is legal:

    /**
     * @jws:parameter-xml xml-map="xml"::
     * <searchData>
     * <query>
     *     <criterion>
     *         <vendorName>Legal Text</vendorName>
     *         <partName><xm:value obj="criterionValue"/></partName>
     *     </criterion>
     * </query>
     * </searchData>
     * ::
     */
    public String searchData(String criterionName, String criterionValue)
    {...}

## XML Maps Change a Service's Interface

When you apply an XML map to a method or a callback, that service's interface (as expressed in its WSDL, for example) changes. The interface reflects the data as it is presented through the map. The map in effect "hides" the underlying Java code.

For example, imagine you have a callback that sends an inner class as one of its parameters. If you have an XML map on the callback, perhaps parsing the inner class's data members to XML elements, the inner class itself may not be visible to clients. When you generate a service control from your service's WSDL, the control will declare a kind of anonymous substitute for inner class prepended with "AnonType_". A client web service using the control must, in turn, import this class, giving the control name as a package name. Note that adding the import statement is handled by WebLogic Workshop when you add the control to a client web service.

## Map Roots Must Be Unique Within a JWS File

Just as with classes inside of JWS files, the root tags of XML maps must be unique within a JWS file. This is because they result at compile time in distinct classes for the types that support them. In the following two XML maps, for example, the <searchRequest> and <SearchRequest> tags occur as root tags. The result will be that the CLASS files needed to support one will overwrite those needed to support the other.

    /**
     * This code will not work as expected! The <searchRequest> tags create a situation
     * in which one map will work while types to support the other are overwritten.
     *
     * @jws:operation
     * @jws:parameter-xml xml-map::
     *     <searchRequest  xmlns="http://www.openuri.org/">
     *         <productName serialNumber="{serialNumber}">{productName}</productName>
     *         <quantity>{quantity}</quantity>
     *     </searchRequest>
     *      * ::
     * @jws:return-xml xml-map::
     *     <SearchRequest  xmlns="http://www.openuri.org/">
     *         <return>{return}</return>
     *     </SearchRequest>
     *      * ::
     */

Note: If you are working on a computer running Windows, the uniqueness must take case into account. Because Windows does not have a case-sensitive file system, a class called searchRequest.class will overwrite a class called SearchRequest.class.

In other words, it's a good practice to list the names of all classes and XML map root tags within a JWS and make sure they're unique with respect to each other.

Related Topics

How Do XML Maps Work?