Online documentation - Websydian v6.0

Users Guide | Patterns Reference | WebsydianExpress | Search

 

Simple Element With Attribute



Introduction

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.

Workaround

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:

  1. In the post point 'Perform DOM processing for Element' (SingleFetch) or the post point 'Before create text node' (InsertRowDangling) test if the field CurrentField<FieldName> is equal to MySimpleElementWithAttribute.
  2. If yes, then call the appropriate DOM function that sets/retrieves the attribute value for the element.

 For more detailed examples please see the following section.

Examples

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.

SingleFetch

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.

InsertRowDangling

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.

InsertRowDangling - attribute in namespace

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.