Identification system
There may be a need for backwards identification of source image of the result element. This is achieved by using gene:id attributes, identifying elements. Because text nodes cannot have attributes, their IDs have to be computed using their position.
You may compute IDs of source nodes in your stylesheet using these rules:
- If the node is an element, simply take the value of its gene:id attribute. This ID attribute value is an integer number, just in case you are terribly curious :)
- If the node is not an element nor an attribute then it is a child of some element and it has an order number. Just compute its ID from the ID of its parent and its zero-based position. Use a semicolon (;) to separate those two values, for example: 5;2.
- Attributes are not ordered so use their qname (in the form of foo or bar:foo if it does have a prefix) instead and separate it by a @ character, for example 5@bar:foo.
- The IKSLibs' IdManager class is used to map those IDs back to nodes, please look there for further information.
When processing output of some previous exporter, you may find two distinctive gene:id attributes with same value - this may happen when the exporter transformed same node into two different document parts. Sometimes you need to differentiate between such attributes - for example PDF-FOP coordinator converts gene:id into XSL-FO native id attributes which are required to be unique. We must ensure that two different ID strings denote the same element. Hence, we define the ID structure as follows:
[parent-id]{; or @} position or attribute-name [,any_string]
where [] denotes an optional part and {} represents choice between two strings. No whitespaces are allowed. The any_string part is ignored when IDs are compared - two IDs are equal if and only if their parent-id are equal or both are missing and position (or attribute-name) are equal. Hence, 2;5,blah, 2;5,foo and 2;5 are equal IDs.
We say that ID is synthetic when it is not present in the source document and needs to be created from another ID. We say that ID is native if it is not synthetic. We see that only IDs denoting elements are native - all other IDs (text, comment, attribute, ...) are synthetic.
Transporting IDs
transporting Here are some tips you may find useful:
- You should transport ids of text, comment and PIs (processing instructions), otherwise the text won't be editable. There is no general rule, how these ids should be transported - text can't contain any attributes. For example, for built-in FO plugin, these ids are transported by encapsulating text into <fo:inline> element that contains the gene:id attribute containing the value of this id.
- Comments and PIs are mostly not displayed in resulting tree. However, if they are, then they have same transportation semantics as text. For example, text of comment should be simply enclosed in <fo:inline> element, as if text was transported. The type of source node will be get from id, so there is no need to specify this type explicitly.
- Even if comment and/or PI is lost (no visible item is produced), it may specify the position of this node in original document, so that this comment/PI is still backwards identifiable. For example, in FO we may specify this position with <fo:inline id="..."/> - it doesn't occupy any canvas space and doesn't harm the presentation in any way.
- Text, comment, PIs and attributes values may be displayed and edited in canvas. There are some restrictions in these nodes' ID transporting. If value is modified somehow (text is added in the middle of text, or some characters are erased (this does not apply to whitespaces in string), then this node's id should not be transported into this place otherwise WYSIWYG text modification may insert text at incorrect place.
There are several possibilities, how source nodes can be transformed:
- 1:1 - one node is transformed to exactly one node. Simple transfer gene:id to new node.
- 1:n - node is transformed to one or node elements. Simply transfer gene:id to all new nodes (it may be enough to transfer emp:id to all roots of trees being created - by common XML sense the node inherits ID from its ascendant).
- n:0 - node is lost, thus invisible when rendered. Just lose the gene:id attribute aswell.
- n:1 - more elements are transformed into one. Let's assume that this possibility is not reducible, for example into 1:1 and n:0 possibility. We must then lose some ids, thus render source nodes editable only indirectly (via the document tree). However, there is a way - you may wrap the IDs into a non-visible elements.
Let's have foo element containing bar element that contains baz element containing some text, and we are trying to render only the text in a FO output document. The result may look like this: <fo:inline gene:id="foo_id"><fo:inline gene:id="bar_id"><fo:inline gene:id="baz_id"><fo:inline gene:id="text_id">text</fo:inline>.... etc
- n:m - again let's assume that this possibility is not reducible. You should try to solve this case in a similar way as the n:1 case.