The data section.

The data section defines a tree structure in the input or output section.

The specification

Example:

<data>
  <contains>
    <contained element="property" />
  </contains>
  <element name="property">
    <description>A property name and value.</description>
    <attribute name="name" required="true" type="PropertyName">
      <description>The property name.</description>
    </attribute>
    <attribute name="value" required="true" type="_text">
      <description>The property value.</description>
    </attribute>
  </element>
</data>

An element can also contain another element or text(pcdata) but not both.

To add an element in another element, add

<data>
  <contains>
    <contained element="property" />
  </contains>
  <element name="property">
    <description>A property name and value.</description>
    <contains>
      <contained element="product" />
    </contains>
    <attribute name="name" required="true" type="PropertyName">
      <description>The property name.</description>
    </attribute>
  </element>
  <element name="product">
...

If you want your element to contain PCDATA, use

<data>
  <contains>
    <contained element="property" />
  </contains>
  <element name="property">
    <description>A property name and value.</description>
    <contains>
      <pcdata />
    </contains>
    <attribute name="name" required="true" type="PropertyName">
      <description>The property name.</description>
    </attribute>
...

Since XINS 1.1.0, it's also possible to include more than one element in the data section:

<data>
  <contains>
    <contained element="packet" />
    <contained element="letter" />
  </contains>
  <element name="packet">
    <description>The packet.</description>
    <attribute name="destination" required="true" type="_text">
      <description>The destination of the packet.</description>
    </attribute>
  </element>
  <element name="letter">
    <description>The letter.</description>
    <contains>
      <pcdata />
    </contains>
    <attribute name="destination" required="true" type="_text">
      <description>The destination of the letter.</description>
    </attribute>
  </element>
</data>

Attributes can also have a default value using the default attribute.

The implementation

The data section is translated into a Java object with the appropriate set methods. Once the object is created, you can add them to the SuccessfulResult using provided add methods.

Example:

SuccessfulResult result = new SuccessfulResult();
Property myProperty = new Property();
myProperty.setName(myName);
myProperty.setValue(myValue);
result.addProperty(myProperty);
return result;

If you had specified that your element could contain another element, the Property class would also have a addProduct(Product) method.

If you had specified that your element could contain a text, the Property class would also contain a pcdata(String) method.

The result

To view what kind of result to expect from a data section, we will define an example in the specification of the function.

<output-data-example>
  <element-example name="property">
    <attribute-example name="name">upgrade</attribute-example>
    <attribute-example name="value">true</attribute-example>
  </element-example>
  <element-example name="property">
    <attribute-example name="name">surname</attribute-example>
    <attribute-example name="value">Doe</attribute-example>
  </element-example>
</output-data-example>

The resulting XML from XINS would then be

<result>
  <data>
    <property name="upgrade" value="true" />
    <property name="surname" value="Doe" />
  </data>
</result>

If your element accepted PCDATA, you can set a value by adding <pcdata-example>My value</pcdata-example> before the <attribute-example>.

You can find some examples of the output data section in the functions demo\xins-project\apis\allinone\spec\DataSection.fnc and demo\xins-project\apis\allinone\spec\DataSection2.fnc.

Data section for the input

Since XINS 1.1.0 it's also possible to send a data section for the request. The definition of the data section is similar to the definition for the output section except that it must be done in the input section. The definition of the example is done using the <input-data-example> element.

This allows you to send complex structures with XINS in the request.

The framework will generate some extra objects and methods to get the values of the input data section. Here is an example:

import java.util.Iterator;
...
Iterator itAddresses = request.listAddress().iterator();
while (itAddresses.hasNext()) {
  Request.Address nextAddress = (Request.Address) itAddresses.next();
  System.out.println(nextAddress.getPostcode());
}

An example is provided with XINS in the function demo\xins-project\apis\allinone\spec\DataSection3.fnc.

Since XINS 1.5.0, if you are using Java 1.5 and deploying on a Java 1.5 application server, you can also benefit from the Java generics feature as demontrated at the end of the next section.

Data section on the client side

On the client side the data section is retreived as an org.xins.common.xml.Element object (javadoc). To get the values in the returned data section, use the methods provided in the Element class such as getAttribute(String localName) or getChildElements(String name).

If you want to send a data section as input, you will need to create an org.xins.common.xml.Element (javadoc) for example by using the org.xins.common.xml.ElementBuilder (javadoc) class. Then you can pass this object to the CAPI call method or to the generated Request object.

Since XINS 1.3.0, the methods and objects are also generated on the client side for the data section. They are generated the same way as they are on the client side. For example, if you want to send a list of address and receive a list of properties, this will look like this:

  • For the request:

    import com.mycompany.myapi.capi.MyFunctionRequest;
    ...
    MyFunctionRequest request = new MyFunctionRequest();
    MyFunctionRequest.Address address1 = new MyFunctionRequest.Address();
    address1.setCompany("McDo");
    address1.setPostcode("12345");
    request.addAddress(address1);
  • For the result:

    import java.util.Iterator;
    import com.mycompany.myapi.capi.MyFunctionResult;
    ...
    MyFunctionResult result = capi.callMyFunction(...);
    Iterator itProperties = result.listProperty().iterator();
    while (itProperties.hasNext()) {
      MyFunctionResult.Property nextProperty = (MyFunctionResult.Property) itProperties.next();
      String propertyName = nextProperty.getName();
      String propertyValue = nextProperty.getValue();
      System.out.println(propertyName + ": " + propertyValue);
    }

    If you are using Java 1.5 or higher and did not set the build.java.version property to a lower version, the generated classes will use the generics feature added to the Java language since Java 1.5. This will simplified your code of using the code:

    import com.mycompany.myapi.capi.MyFunctionResult;
    ...
    MyFunctionResult result = capi.callMyFunction(...);
    for (MyFunctionResult.Property nextProperty : result.listProperty()) {
      String propertyName = nextProperty.getName();
      String propertyValue = nextProperty.getValue();
      System.out.println(propertyName + ": " + propertyValue);
    }