Generating XML from Objects
The output serialization API generates XML from Smalltalk objects. Each Smalltalk object can provide a custom 'serialization configuration' which contains the rules that a serializer uses to create XML from an object. Serialization configuration objects can be stored in the XML object cache and retrieved for usage during object serialization. Below is a description of the contents of a serialization configuration (AbtXmlSerializationConfiguration).
dtd
The AbtDOMDocumentType that describes the XML structure for objects to be serialized.
formattingEnabled
A boolean to indicate whether the rendered XML stream should include formatting characters like tabs and carriage returns. The default is true.
mappingSpec
The AbtXmlMappingSpec that contains the mapping rules for the objects being serialized.
namespaceMappings
A KeyedCollection that contains prefix->uri associations that are used during serialization to prefix namespace qualified elements.
objectCache
The AbtXmlObjectCache used to retrieve XML artifacts during serialization. Information that is not passed in the serialization configuration is looked up in the objectCache.
printTypes
A boolean to indicate whether the default XML serializer should render schema type name as an attribute of the element. The default is true.
o ie) <myName xsi:type="xsd:string">VisualAge</myName>
schema
The AbtXmlSchema where the types for serialized objects can be resolved.
serializer
The output serializer used to render the XML for an object. The default value is derived by evaluating the code 'AbtXmlOutputSerializer default'.
AbtXmlSerializationConfiguration contains additional protocol to allow custom configurations to be supplied for child elements. Use the method #useConfiguration:forElementNamed:inNamespace: to create a custom serialization configuration for a specific child element/namespace pair.
The example below uses the cached serialization configuration named 'namespace1' when serializing the element named 'childElement' in namespace 'namespace2'.
| config childConfig |
" Constructs a default serialization configuration by resolving required
objects in the AbtXmlObjectCache using the passed cache key "
config := AbtXmlSerializationConfiguration forKey: 'namespace1'.
" Declare any namespace associations required for proper serialization "
config
declarePrefix: 'myn' uri: 'namespace1' ;
declarePrefix: 'vast' uri: 'Smalltalk'.
" Code assumes that a serialization configuration named 'namespace2' is stored in the active
AbtXmlObjectCache "
childConfig := AbtXmlObjectCache current serializationConfigurationNamed: 'namespace2'.
config
useConfiguration: childConfig
forElementNamed: 'childElement'
inNamespace: 'namespace2'.
config
Default serialization configuration
If a custom serialization configuration is not supplied, the XML support constructs a default during serialization using the abtXmlCacheKey of the target object. By default, the value of the abtXmlCacheKey is the class name of the receiver object. Individual objects can override the method abtXmlCacheKey to supply a more suitable value. Using a common cache key allows the VA Smalltalk XML support to reconcile multiple disparate objects (ie. mappingSpecs, schemas, serializationConfigurations) from the object cache. When using XML schemas, it is logical for the abtXmlCacheKey of an object to be the namespace URI of the schema element that it represents. Related mapping specifications and schemas are stored and resolved using the same key.
Default serializer behavior
VA Smalltalk XML support provides classes that are used to serialize objects into XML based upon the level of information present in the active serialization configuration. Objects are most accurately serialized when both a mapping specification and a DTD (or schema) is supplied. Below is a brief description of the serializer behavior when different serialization inputs are supplied.
DTD
A mapping spec must be supplied when serializing with a DTD. The mapping spec is used to determine the name and sequence for the XML subelements, and the DTD is used to determine which of the object's attributes should be rendered as XML attributes (as opposed to XML elements). The default DTD serializer is AbtXmlDtdOutputSerializer
Schema
Object is serialized by applying the structure specified in the schema. If a mapping spec is supplied, it is used to resolve Smalltalk attribute names during rendering. The default schema serializer is AbtXmlSchemaOutputSerializer.
Mapping specification
Used to resolve the attribute contents during rendering. Attribute mappings are rendered as XML attributes for the active element. Subelement mappings are rendered as XML elements. The default serializer is AbtXmlOutputSerializer
If no serialization rules are supplied, the AbtXmlOutputSerializer renders each instance variable as a subelement of the top-level element. The class name and each instance variable are generated as an XML start and end tag with the value of the variable printed between the two tags. For example, execution of the following code:
(Point x:5 y:10) abtXmlPrintString
results in the following XML:
<Point>
<x>5</x>
<y>10</y>
</Point>
To override the default serializer and control the behavior of output serialization, create a custom serializer and make it the default.
• ie) AbtXmlOutputSerializer default: MySerializer current
Note:
The VA Smalltalk XML output serialization provides well formed but not validated XML.
Output Serialization Methods
A serialization configuration can be supplied to customize the serialization behavior for an object. If a custom configuration is not provided, a default is constructed. Required serialization inputs for the object being serialized are resolved via the overridable protocol that follows.
^AbtXmlObjectCache current mappingSpecNamed: 'MySpecName'.
The following overridable methods are provided in the Object class:
abtXmlCacheKey
An object (typically a String) used as the key for looking up XML serialization artifacts in the object cache.
abtXmlDtd
Returns an AbtDOMDocumentType that can be used to validate parsed XML streams or provide rules for serializing objects as XML.The default implementation of this method uses the abtXmlCacheKey of the receiver to query the AbtXmlObjectCache for a suitable DTD.
abtXmlMappingSpecification
Returns an AbtXmlMappingSpec that contains rules for mapping XML elements into Smalltalk domain objects and serializing domain objects as XML. The default implementation of this method uses the abtXmlCacheKey of the receiver to query the AbtXmlObjectCache for a suitable schema.
abtXmlNamespaceMappings
Returns a KeyedCollection that contains namespace prefix->uri assocations. The default implementation answers nil.
abtXmlPrintAnyTypeOn:context:
This method is sent during XML serialization by the schema serializer when an element with schema type 'anyType' attempts is to be serialized. Method can be overridden. The default implementation invokes the abtXmlPrintOn:context: method of the receiver.
abtXmlPrintFeatures
Returns the features to include when printing an object as XML. Users can override this method if the implementation does not answer the required features. For example, users might override abtXmlPrintFeatures to remove certain features if those features should not be included in the XML.
abtXmlPrintOn: aStream
The abtXmlPrintOn: method works in the same way as the Smalltalk printOn: method. The abtXmlPrintOn: method takes a WriteStream, aStream, for an argument and outputs its XML representation to the passed stream.
abtXmlPrintOn:context:
This method is similar to abtXmlPrintOn:. A shared serialization context, AbtXmlSerializationContext, is passed. The context object allows parent objects to share information with child objects during serialization. By default, serialization contexts are shared with child objects during rendering. To disable context sharing, set the context property shareWithSubElements to false. This will cause a new serialization context to be created for each child object that is rendered.
abtXmlPrintString
The abtXmlPrintString method relies on abtXmlPrintOn (similar to how the printString method relies on the printOn method).
abtXmlPrintUsing:
This method functions in the same manner as abtXmlPrintString; however, it allows a custom serialization configuration (or context) to be passed in and used during object rendering.
abtXmlSchema
Returns an AbtXmlSchema that can be used to validate parsed XML streams or provide rules for serializing objects as XML. The default implementation of this method uses the abtXmlCacheKey of the receiver to query the AbtXmlObjectCache for a suitable schema.
abtXmlSerializationConfiguration
Returns an AbtXmlSerializationConfiguration that is holds the serialization rules for a Smalltalk domain object. The default implementation of this method uses the abtXmlCacheKey of the receiver to query the AbtXmlObjectCache for a cached configuration. If a cached configuration is not located, a default serialization is constructed by attempting to resolve any objects that are utilized by serialization (ie. mapping spec, schema, dtd).
Changing the DOM and regenerating XML
The DOM classes contain implementations of the abtXmlPrintOn: method. This allows you to print out the XML that is parsed. For example, you can parse XML, change the DOM, and print the modified DOM as XML. If the original XML was validated XML, it is still validated XML.
Generating XML from the DOM
You can generate XML from a DOM without using the mapping support. The mapping support supplied with VA Smalltalk is only necessary when mapping parsed DOM objects into custom business objects.
For example, you can parse an XML stream containing the representation of a 'Customer' and derive an instance of a Smalltalk 'Customer' object. If the DOM is manipulated directly, there is no need for mapping. You can send the message abtXmlPrintString to a DOM document instance to derive the XML string that represents that DOM.