DOM Augmentation
Overview
When formatting from an XML DOM stream (.xd tag) in PTC Arbortext Layout Developer, it is possible to add information to that DOM both before formatting and during the formatting process. Pre-formatting augmentation is controlled using an augmentation control stream. XPath extension functions and DOM commands manage the augmentation that can occur during formatting. These processes are used extensively in the Arbortext Styler integration to handle generated text and to track certain information during formatting.
DOM augmentation is used to add nodes to the DOM tree. Those nodes could be a table of contents, generated text, or metadata, depending on requirements. DOM augmentation provides a way to perform these tasks without using XSLT or composition pipeline processes. Inline augmentation can be applied conditionally, testing any condition available to PTC Arbortext Layout Developer. DOM augmentation also supports the adding of private user data to DOM nodes.
Augmentation with Augmentation Control Stream
Context control augmentation happens before the formatting process has started. It applies the augmentations to a clean DOM represented by the source XML instance. All augmentations occur only once.
This level of augmentation is applied with a control stream The augmentation control stream is the same as a context control stream (tag type .cx). The Arbortext Styler integration uses the same control stream for augmentation as for context matching. The augmentation control stream is applied to a content stream using either the augmentationCtrl property of the fStream object or the ttreeaug macro.
A match keyword specifies the context at which augmentation must take place. Further keywords can follow match to apply augmentation:
• addBefore — tells PTC Arbortext Layout Developer which DOM fragment (or node from a DOM) to add before the content of the matched node
• addAfter — tells PTC Arbortext Layout Developer which DOM fragment (or node from a DOM) to add after the content of the matched node
• augmentUserData — applies a DOM user data key and value pair to the matched node. A match can have more than one of these keywords.
• augmentReference — adds a reference tag PI to the content stream at the match location
• augmentXPath — applies an XPath expression at the location of the match to apply inline DOM augmentation. A match can have more than one of these keywords.
These keywords are used to add simple information into the DOM.
More complex information can be added using the nodeset functionality. This is used to add items such as tables of contents into the DOM at matched locations. The augmentNodeset keyword requires a separate control stream to specify which contexts should populate the nodeset and what actions to take for them.
• augmentNodeset — tells PTC Arbortext Layout Developer which augmentation control stream to use to gather a set of nodes to insert at the match location. The set of nodes is provided as a series of matches in the supplemental control stream. When PTC Arbortext Layout Developer has gathered the nodes, they are inserted in document order into the DOM.
The augmentNodeset keyword can also take a second argument to specify the scope of the nodeset gathering process. This is the name or location path of an ancestor of the current matched node. For example, it is possible to create a nodeset scoped to the current chapter in a book or the current section in a manual.
Inline Augmentation Using XPath
Inline DOM augmentation is carried out using PTC Arbortext Layout Developer’s XPath extension functions. These functions act as inline commands to apply DOM augmentation whenever the commands are encountered in the formatting process. They must be treated with caution. It is possible to add multiple versions of the same augmentation to the DOM tree and end in an infinite loop. There are extension functions to help avoid this situation.
In the Arbortext Styler integration, inline augmentation is used to apply conditional generated text and to store user data on nodes to track formatting behavior.
The extension functions for adding nodes to the DOM are:
• x3b2:add-before() — adds a DOM node to the specified node just before the content of the specified node starts. For example:
formatting.evaluateXPath(‘x3b2:add-before(“tx1#/doc/p[1]”, 1, self::node(), self::node())’);
In this example, the node specified by the location path “tx1#/doc/p[1]” is added to the start of the current node. This location path uses the streamName#locationPath syntax. It specifies that the first <p> element in <doc> from the DOM stream called tx1 is selected. To add the whole of the contents of that DOM stream, reference the tag name only, here tx1.
The last self::node() location path specifies the node to which the augmentation is applied.
The first self::node() specifies the reference node that is applied to the augmented node
The 1 flag is undocumented.
• x3b2:add-after() — works in the same way as add-before(), but adds the specified DOM node to the end of the content of the node identified by the last location path
• x3b2:clear-before() and x3b2:clear–after() — remove any DOM augmentations that have been added before or after the content of the specified node
As inline DOM augmentation is an additive process, it is good practice to clear any inline augmentations before adding a new one. This helps to avoid the adding of multiple copies of the same augmentation.
• x3b2:set-reference() — adds a special processing instruction to the DOM that calls a specified PTC Arbortext Layout Developer tag.
Adding a reference node ensures that the DOM structure is not changed extensively. The addition of undefined element nodes changes XPath navigation.
For example:
formatting.evaluateXPath('x3b2:set-reference("myTag", 1, self::node());
would add the processing instruction <?A3B2T myTag?> into the DOM before the content of the node specified by the location path and after any other augmentations. This processing instruction simply calls the tag named myTag.
The extension functions for adding user data are:
• x3b2:set-userdata() — sets user data on a node
For example:
formatting.evaluateXPath('x3b2:set-userdata("myDataItem", "value")');
adds a user data item called myDataItem to the current node, with the value of value.
The XPath expression can also add user data to a remote node by adding a location path parameter, such as:
formatting.evaluateXPath('x3b2:set-userdata("myItem", "thisValue", /book/chap[1]/sect[3]/para[4])');
• x3b2:get-userdata() — retrieves a piece of user data once it has been set
For example, to retrieve the specified user data from the current node:
formatting.evaluateXPath('x3b2:get-userdata("myItem")');
For example, to retrieve specified user data from a remote node using a location path:
formatting.evaluateXPath('x3b2:get-userdata("myItem", /book/chap[1]/sect[3]/para[4])');
• x3b2:has-userdata() — tests for the presence of a user data key on a specified node, returning a boolean value
For example, to test for a data key on the current node:
formatting.evaluateXPath('x3b2:has-userdata("test")');
For example, to test for a data key on a remote node using a location path:
formatting.evaluateXPath('x3b2:has-userdata("test", /book/chap[1]/sect[3]/para[4])')
Augmentation Using DOM
These XPath extension functions for augmenting the DOM have DOM node equivalent methods:
• fxNode.augmentBefore() — equivalent of the x3b2:add-before() XPath extension function, acting on the current DOM node
• fxNode.augmentAfter() — equivalent of the x3b2:add-after() XPath extension function, acting on the current DOM node
• fxNode.augmentReference() — equivalent of the x3b2:set-reference() XPath extension function, acting on the current DOM node
The user data extension functions also have DOM equivalents:
• fxNode.setUserString() — provides a method to set the specified user string on the node, for example:
formatting.currentXMLNode.setUserString("test", "value");
• fxNode.getUserString() — provides a method to get the specified user string from the node, for example:
formatting.currentXMLNode.getUserString("test");
Properties of Augmented Nodes
DOM augmentation adds information into the DOM that is being formatted. This information cannot be seen when clicking into the context stream representing the DOM. Augmentations are hidden from the user and are also hidden from XPath location paths. There are PTC Arbortext Layout Developer options to handle this feature.
• If you want to see the DOM from which PTC Arbortext Layout Developer is formatting, you can use the ttreedump macro. This serializes out the formatting DOM to either an external file or an internal tag. The PTC Arbortext Layout Developer extensions to DOM also provide an augSerialize() method to serialize out the augmented node.
• When using the PTC Arbortext Layout Developer XPath extension function x3b2:get-path() inside an PTC Arbortext Layout Developer tag for a node that has been augmented onto a DOM, a hash symbol # precedes the element. This denotes that the element is part of augmentation. The hash symbol precedes the top element in the hierarchy of the augmentation. Use the hash when looking into augmentation content. Without the hash, augmentation is not visible.
• The fxNode object in PTC Arbortext Layout Developer’s extension to DOM also has properties that allow navigation within augmentation. augParentNode, augNextSibling, augPreviousSibling, augFirstChild, and augLastChild are the equivalent to the normal DOM properties but work within augmentation.
The fxNode object also provides hasAugmentation and withinAugmentation properties to allow you to determine whether to use these properties in your DOM-based navigation.
Reference Nodes
When augmentation from a control stream occurs, PTC Arbortext Layout Developer adds some information to the augmentation to indicate where it originated. This is the referer node information.
When applying DOM augmentation using inline commands, you can also set this information by specifying a location path, as described previously.
In XPath, this information is available through the PTC Arbortext Layout Developer extension node test refnode(). For example:
formatting.evaluateXPath('x3b2:get-path(self::refnode())');
Inside DOM, this information is available through the fxNode extension property fxNode.augRefererNode. For example:
formatting.currentXMLNode.augRefererNode.getNodePath();
Both examples returns the location path of the source of the DOM augmentation.
The reference node has several uses. For example, if you are using DOM augmentation to build a table of contents, the reference node information for each item in the generated code has the location of the item’s source. The location can then be used to evaluate the item’s page number. The location information can be used in other XPath expressions that reference that original location as the context node, and drive numbering, styling, or other formatting.