Online documentation - Websydian v6.1 |
To make the XML model in TransacXML as similar to the way you normally read from relational table entities, TransacXML distinguishes between simple elements and complex elements.
Simple elements are modeled as fields, while complex elements are modeled as entities.
This means that in a construct like this:
<MyElement>123</MyElement>
MyElement is modeled as an ElementField, while in a construct like this:
<MyElement>
<SubElement1>123</SubElement1>
<SubElement2>456</SubElement2>
<MyElement>
MyElement is modeled as an XMLELement (and the elements SubElement1/SubElement2 are modeled as ElementFields).
In a construct like this:
<MyElement att="123"></MyElement>
MyElement is also modeled as an XMLElement (and the attribute att is modeled as an AttributeField).
Or in other word, when a element only contains a value, it is modeled as a field, and when an element contains other elements and/or attributes, it is modeled as an entity.
However, the XML standard allows structures that belongs to both of these cases - the most common example is:
<MyValue Currency="USD">1000</MyValue>
MyValue contains a value (1000) - and an attribute (Currency) - so it really could be modeled as an ElementField (but then we couldn't handle the attribute) or as an XMLElement (but the we couldn't handle the value).
Another example could be:
<MyElement>
<SubElement1>123</SubElement1>
abcd
<SubElement2>456</SubElement2>
</MyElement>
In this case, MyElement contains both subelements and a value - and as such, it could be modeled as both an ElementField and as an XMLElement.
This document describes how these structures can be modeled.
In W3C schemas, these structures are specified by adding the attribute mixed with the value true to the complexType that describes the complex element.
This just specifies that you can add text nodes as direct children to the complex element. It is not possible to specify the location of the text node and it is not possible to specify any constraints for the values or the types of the text nodes.
Two new fields, ComplexValue and ComplexValueUT has been created in the WSYXML Plex library model.
Fields inheriting from these two fields can act as placeholders for values that are placed directly under the complex element.
The field ComplexValueUT is an untyped field that can be used in the same cases where you use ElementFieldUT and AttributeFieldUT. In the following description will use ComplexValue as the abstract field. But you can just as well use the ComplexValueUT field - you must just remember to also specify a type for the field.
The ComplexValue fields are used much like the AttibuteFields and the ElementFields, they are added to an XMLElement by specifying a ENT has FLD triple and the sequence of the has triples determines the position of the field in the complex element.
However, as the ComplexValue fields only are placeholders for text nodes, the name of the ComplexValue field does not correspond to anything in the document, and they are unaffected by namespaces. This also means that inheriting from the LongName and/or NamespaceAware will have no effect for ComplexValue fields.
In general, the complexValue fields are easy to use, just add a field inheriting from WSYXML/ComplexValue or WSYXML/ComplexValueUT to the XMLElement entity using a has triple - and you have the capability to assign a text node to the specified position in the complex element that and to read the value of a text node that is the direct child of the complex element.
This example shows how you can model the following structure:
<MyValue Currency="USD">1000</MyValue>
Source Object | Verb | Target Object |
---|---|---|
MyValue | is a ENT | XMLElement |
MyValue.Fields | field FLD | Currency |
MyValue.Fields | field FLD | Value |
MyValue | has FLD | MyValue.Fields.Currency |
MyValue | has FLD | MyValue.Fields.Value |
MyValue.Fields.Currency | is a FLD | AttributeField |
MyValue.Fields.Value | is a FLD | ComplexValue |
The InsertRow function for the MyValue XMLElement entity will contain the two fields MyValue.Fields.Currency and MyValue.Fields.Value in the Data variable.
Specifying a value for the MyValue.Fields.Currency input field will populate the value for the Currency attribute.
Specifying a value for the MyValue.Fields.Value input field will set the specified value as a child text node for the MyValue element (1000 in the example shown).
The SingleFetch function will also have the two fields in the data variable (output).
The SingleFetch function will populate the MyValue.Fields.Currency output field based on the value found in the Currency attribute.
The SingleFetch function will populate the MyValue.Fields.Value field based on the value found in the textnode that is a child of the MyValue element (if any textnode is present).
This means that you will now be able to read and write a text that is the direct child of the MyValue element.
Please note that the name of the field inheriting from ComplexValue has no significance - as the textnode has no name in the XML document.
This example shows how you can model the following structure:
<MyElement>
<SubElement1>123</SubElement>
abcd
<SubElement2>456</SubElement>
</MyElement>
Source Object | Verb | Target Object |
---|---|---|
MyElement | is a ENT | XMLElement |
MyElement.Fields | field FLD | SubElement1 |
MyElement.Fields | field FLD | SubElement2 |
MyElement.Fields | field FLD | Value |
MyElement | has FLD | MyElement.Fields.SubElement1 |
MyElement | has FLD | MyElement.Fields.Value |
MyElement | has FLD | MyElement.Fields.SubElement2 |
MyElement.Fields.SubElement1 | is a FLD | ElementField |
MyElement.Fields.SubElement2 | is a FLD | ElementField |
MyElement.Fields.Value | is a FLD | ComplexValue |
The InsertRow Data input variable and the SingleFetch Data output variable will contain the three fields:
MyElement.Fields.SubElement1, MyElement.Fields.Value, MyElement.Fields.SubElement2
The InsertRow function will place the text node between the two SubElement fields because the sequence of the has triples specifies this position.
The XML standard allows an element to have several text nodes as childnodes:
<MyElement>
<SubElement1>123</SubElement>
abcd
<SubElement2>456</SubElement>
efgh
</MyElement>
You can also use the ComplexValue objects to model this - as follows:
Source Object | Verb | Target Object |
---|---|---|
MyElement | is a ENT | XMLElement |
MyElement.Fields | field FLD | SubElement1 |
MyElement.Fields | field FLD | SubElement2 |
MyElement.Fields | field FLD | Value |
MyElement.Fields | field FLD | Value2 |
MyElement | has FLD | MyElement.Fields.SubElement1 |
MyElement | has FLD | MyElement.Fields.Value |
MyElement | has FLD | MyElement.Fields.SubElement2 |
MyElement | has FLD | MyElement.Fields.Value2 |
MyElement.Fields.SubElement1 | is a FLD | ElementField |
MyElement.Fields.SubElement2 | is a FLD | ElementField |
MyElement.Fields.Value | is a FLD | ComplexValue |
MyElement.Fields.Value2 | is a FLD | ComplexValue |
The InsertRow function will insert the value specified for the field Value between the two SubElement fields and will insert the value specified for Value2 after the field SubElement2.
The SingleFetch function will place the value of first text node it finds in the document in the output field Value and it will place the value of the second textnode it finds in the output field Value2.
The SingleFetch function works in the following manner:
For each ComplexValue field that is specified for the XMLElement, the SingleFetch function will search in the XML document for a text node that is the direct child of the complex element that corresponds to the XMLElement. The value of the first text node found will be assigned to the first ComplexValue field, the value of the second text node found will be assigned to the second CompleValue field etc.
The consequences of this is probably best shown by looking at some examples.
The examples will all use the Plex definitions described in example 3.
Given a document:
<MyElement>
<SubElement1>123</SubElement>
abcd
<SubElement2>456</SubElement>
efgh
</MyElement>
The values assigned by the SingleFetch function to the output fields will be:
Value = abcd
Value2 = efgh
Given a document:
<MyElement>
<SubElement1>123</SubElement>
<SubElement2>456</SubElement>
efgh
</MyElement>
The values assigned by the SingleFetch function to the output fields will be:
Value = efgh
Value2 = ''
As the first text node that occurs is efgh, it is assigned to the first ComplexValue field. As it is the only one, no value is assigned to the second ComplexValue field.
Given a document:
<MyElement>
ijkl
<SubElement1>123</SubElement>
abcd
<SubElement2>456</SubElement>
efgh
</MyElement>
The values assigned by the SingleFetch function to the output fields will be:
Value = ijkl
Value2 = efgh
As the first text node is ijkl, it is assigned to the first ComplexValue field. As the second text node is abcd, it is assigned to the second ComplexValue field.
It is quite rare that a complex has more than one text node as a direct child - so this limitation should only very rarely be a problem. On the other hand the W3C schema standard does not provide any options for specifying the number of text nodes or the position of these text nodes in the complex element. This means that there are no way to be sure that the provider of the XML document has not added more text nodes than you expect to the document.
The InsertRow function has no such problems as it is in full control of where the text nodes will be inserted. The text nodes are always inserted according to the position of the fields determined by the Plex model.