# Transformation Source

`XM_XSLT_SOURCE` is an interface for the various sources of data, both for source documents and stylesheets, along with routines to build a tree representation of the data.

## The interface

The interface has deferred features `set_system_id (a_system_id: STRING)` and `system_id: STRING` for naming the source. But the principal deferred feature is `send (a_parser: XM_PARSER; a_receiver: XM_XPATH_RECEIVER; is_stylesheet: BOOLEAN)`.

`Send` is called by the system to build a representation of the data which can be used by the stylesheet compiler and/or the transformer. The meaning of the arguments is as follows:

`a_parser: XM_PARSER`
  This is an XML parser configured with a suitable entity resolver and string mode. Your implementation can use this to start the conversion of XML text data into events for the receiver. If your data source is not of a nature that requires parsing by an XML parser, then you still may want to make use of the entity resolver (though this seems unlikely). You certainly must honor the string mode setting when creating events to send to the receiver.
`a_receiver: XM_XPATH_RECEIVER`
  This is the receiver that will ultimately build the instance of the XPath data model. it will normally be a chain of receivers, so as to implement the correct stripping rules. But as far as the implementer is concerned, all you have to do is to call the events on the receiver in the correct order. This will be documented (in the future) as part of the XPath library documentation. In the meantime, look at `XM_XPATH_CONTENT_EMITTER` for details of how to do this (sorry).
`is_stylesheet: BOOLEAN`
  This argument is present so that your implementation may choose to behave differently when building a stylesheet module, from when building a source document.

In summary, when `send` is called, an implementation must check the string mode on the supplied parser, and then generate an event stream to the receiver.

## Implementations provided by the XSLT library

The system provides the following implementation:

`XM_XSLT_URI_SOURCE`
  This implementation treats the `system_id` as a URI identifying a source of XML text data, and uses the supplied XML parser to supply (via it's configured entity resolver) a stream of events (see `XM_CALLBACKS` and `XM_DTD_CALLBACKS`), and converts them, by a series of filters, into a stream of `XM_XPATH_RECEIVER` events.

  This class provides an additional feature, `send_from_stream`, which is used by the library for xsl:import, xsl:include and document() processing. Your own implementations should not implement this rotuine, as it will not be called by the library.

Possible future library-supplied implementations include `XM_XSLT_RECEIVER_SOURCE` and `XM_XSLT_XM_CALLBACKS_SOURCE`, to direct existing event streams to the receiver. The former may be need for simple pipeling of multiple transformations. The latter could be useful for bridging between application which are already programmed to use the `XM_CALLBACKS` interface, and the XSLT library. I can also envisage a variation on the latter, `XM_DOCUMENT_SOURCE`, where an `XM_DOCUMENT` is turned into an XPath data model. This will be expensive on memory (two representations of the same tree in memory). An alternative approach is to virtualize an XPath data model over an `XM_DOCUMENT`. This would be more expensive on CPU cycles.

## When to write your own implementation

Normally, you will not need to write an implementation of `XM_XSLT_SOURCE`. If you have a mechanism for supplying XML data in a textual form, and a suitable URI scheme to associate with it, then you should only have to implement `XM_URI_RESOLVER`. In this case, `XM_XSLT_URI_SOURCE` will handle your data source transparently. Only when your data source cannot be supplied as a `KI_CHARACTER_INPUT_STREAM` supplying XML text, will you need to write an `XM_XSLT_SOURCE`.

If you cannot write an (or use an existing) implementation of `XM_URI_RESOLVER` for your data source, then you cannot use that data source as an xsl:import, xsl:include or document() or doc() source.