The data section defines a tree structure in the input or output section.
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 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.
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
.
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.
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); }