Online documentation - Websydian v6.0 |
Users Guide | Patterns Reference | WebsydianExpress | Search |
By default a simple element in TransacXML is not allowed to have attributes. This restriction is caused by simple elements and attributes being modeled in CA Plex as fields and that there is not a simple way to model the relation between these two fields.
<value currency="USD">100</value>
Fortunately there is an easy workaround to this restriction and the remainder of this document describes the changes that must be applied to the CA Plex XML model in order to model a simple element with attributes.
To model a simple element with attributes in the XML model first model the simple element as described in the implementation guide.
For each attribute element belonging to the simple element create a field that is used to hold the data value for the attribute. The field can be any type. The only requirement is that the chosen field type must be capable of storing the expected data value.
The attribute field for a simple element must NOT inherit from any of the abstract simple element fields (ElementField, RepeatingElementField, or ElementFieldUT)
Add the attribute fields created above to the same entity as the simple element field (see table below for triple example).
MyOrder | is a ENT | XmlElement |
has FLD
|
MySimpleElementWithAttribute | |
MyAttribute | ||
MySimpleElementWithAttribute | is a FLD | ElementField |
MyAttribute | is a FLD | DOMString |
In any of the XML functions where the simple element with attributes occurs the following steps are necessary:
For more detailed examples please see the following section.
The examples show how to extend TransacXML so it can fetch and insert data values for attributes that belongs to a simple element. In the example it is assumed that a complete XML model has been created in CA Plex and that the simple element and its attribute has been modeled as described above.
In addition to this the following triples should be created:
MyFieldName | is a FLD | WSYXML/FieldName |
value VAL | MySimpleElementWithAttribute | |
value VAL | MyAttribute |
The literal values for the two value objects should correspond to the actual names for the simple element and its attribute; in this example the literal values are 'MySimpleElementWithAttribute' and 'MyAttribute'.
For simplicity the examples does not contain any error checking. When implementing the examples it is strongly recommended to insert error checking after each call to a DOM function.
To extend a SingleFetch function so it can fetch the data value for an attribute belonging to a simple element the following code must be inserted in the post point 'Perform DOM processing for Element':
If CurrentField<FieldName> == <MyFieldName.MySimpleElementWithAttribute>
If Local<ChildNode> != <ChildNode.NULL>
Call DomInterfaces.Element.getAttribute
// Map Local<ObjectStoreReference>
// Map Local<ChildNode>
// Map
<MyFieldName.MyAttribute>
Cast Output/Data<MyAttribute>,
DomInterfaces.Element.getAttribute/Output<AttrValue>
Else
Set Output/Data<MyAttribute> = <MyAttribute.*Blank>
If the attribute belongs to a namespace then use the function DomInterfaces.Element.getAttributeNS instead of DomInterfaces.Element.getAttribute.
To extend an InsertRowDangling function so it inserts the data value for an attribute belonging to a simple element, insert the following code in the post point 'Before create text node':
If CurrentField<FieldName> == <MyFieldName.MySimpleElementWithAttribute>
If Local<CreateElement> == <CreateElement.Yes>
Call DomInterfaces.Element.setAttribute
// Map Local<ObjectStoreReference>
// Map Local<DataElement>
// Map <MyFieldName.MyAttribute>
// Map Input/Data<MyAttribute>
By changing the InsertRowDangling, the InsertRow function is also changed - as InsertRow inherits from InsertRowDangling. Just remember to regenerate and build the InsertRow function as well as the SingleFetch and the InsertRowDangling functions.
The case where an attribute is in a namespace, inserting the attribute demands a few more steps.
You can always recognize if the attribute is in a namespace by checking if the attribute name has the form:
prefix:name - in the following example, pf is the prefix.
<value pf:currency="USD">100</value>
To find out what the namespace is, find the namespace declaration for the prefix - in the following example of a namespace declaration, www.websydian.com/simpleelement is the namespace:
xmlns:pf="www.websydian.com/simpleelement"
In the example, we will just assign the name, namespace and prefix for the attribute using values - the relevant literal values would be:
MyFieldnamespaceURI.attributenamespace = www.websydian.com/simpleelement
MyFieldprefix.attributeprefix = pf
MyFieldName.attributename = currency
To extend an InsertRowDangling function so it inserts the data value for an attribute in a namespace belonging to a simple element, create the following triples:
MyFieldnamespaceURI | is a FLD | WSYXML/FieldnamespaceURI |
MyFieldprefix | is a FLD | WSYXML/Fieldprefix |
MyFieldName | is a FLD | WSYXML/FieldName |
MyXmlElement.InsertRowDangling | variable VAR | AttributeValues |
...as SYS | Local | |
MyXmlElement.InsertRowDangling | local FLD | MyFieldnamespaceURI |
...for VAR | AttributeValues | |
MyXmlElement.InsertRowDangling | local FLD | MyFieldprefix |
...for VAR | AttributeValues | |
MyXmlElement.InsertRowDangling | local FLD | MyFieldName |
...for VAR | AttributeValues |
And insert the following code in the post point 'Before create text node':
If CurrentField<FieldName> == <MyFieldName.MySimpleElementWithAttribute>
Set AttributeValues<MyFieldnamespaceURI> = <MyFieldnamespaceURI.attributenamespace>
Set AttributeValues<MyFieldprefix> = <MyFieldprefix.attributeprefix>
Set AtrributeValues<MyFieldName> = <MyFieldName.attributename>
Call DomInterfaces.Element.CreateAttributeNSWithPrefix
// Map Local<ObjectStoreReference>
// Map Local<ObjectDocument>
// Map AttributeValues<MyFieldnamespaceURI>
// Map AttributeValues<MyFieldprefix>
// Map AttributeValues<MyFieldName>
Call WSYDOM/DomInterfaces.Element.setAttributeNodeNS
// Map Local<ObjectStoreReference>
// Map DomServices.CreateElementNSWithPrefix/Output<ObjectElement>
// Map DomServices.CreateAttributeNSWithPrefix/Output<ObjectAttr>
Call WSYDOM/DomInterfaces.Node.nodeValue_set
// Map Local<ObjectStoreReference>
// Map DomServices.CreateAttributeNSWithPrefix/Output<ObjectAttr>
// Map Input/Data<MyXMLElement.Fields.MyAttribute>
By changing the InsertRowDangling, the InsertRow function is also changed -
as InsertRow inherits from InsertRowDangling. Just remember to regenerate and
build the InsertRow function as well as the SingleFetch and the
InsertRowDangling functions.
Of course, you can assign the values of the three fields in the variable AttributeValues using values retrieved from an ini-file, or found using meta
code in Plex, if you do not just want to assign using literals for values.