| | Towards an SGML Diff Using Temporal Documents |
| | A method to develop an SGMLdiff
is presented. The extendible approach is based on a change-oriented model for structured documents containing e.g. objects of type `data', `element', `attribute', or `link'. The difference between two documents A and B is computed and expressed as a sequence of changes that must be incrementally performed on the objects in A in order to obtain the state B. |
| | Equivalence and changes in SGML documents |
| | Companies that must handle huge amounts of technical documentation can use SGML to mark up their documents in order to process, interchange, and archive them independently of any particular proprietary format. An author often faces different versions and variants of a document. In case these are two SGML document instances that are similar, but where the relation between them is not clear, he needs a meaningful description of their differences. |
| | As SGML is used to encode additional information about thestructure
of a document an SGMLdiff
should reflect the data structure of the documents it compares. It is not enough to get a description of differences between two SGML document instances on the basis of their unstructured textual contents. |
| | The question of expressing differences is closely connected to the notion of identity for the components of an SGML-document. As
state, the SGML standard has little to say about change management. The reason for this is that documents are traditionally perceived as static entities that do not change on the contrary, a document is used tofix
a certain state of the documented information. From this point of view, concepts to express what remains `the same' as the document is changed are not needed. |
| | Nowadays, more and more documents are put online and can therefore easily be updated. This raises important questions about consistency, redundancy, and correctness of the information, and the effectiveness of the underlying work processes
: how can different versions of a document be compared? Is it possible to trace the evolution of the information encoded in an SGML document? And since most documents contain a multitude of copied parts, how can I guarantee that my change does not affect the correctness of the document? Is it necessary to perform a similar change on each copy or is some other editing needed to restore the consistency of the document? |
| | The aim of this paper is to propose a method to build an SGMLdiff
that computes the difference between two SGML document instances A and B as the sequence of changes that would produce B if incrementally performed on A. The task of developing such an SGMLdiff
is threefold: first, the object types of an SGML document must be determined, and second the possible changes for those objects have to be specified. Finally an algorithm is needed to compute the delta between two documents. |
| | The traditionaldiff
utility is not appropriate for the task of comparing two SGML instances, mainly because it operates on plain text files and computes a list of deleted, modified or new lines. Though SGML documents are also encoded in one or more files using the ASCII character set, a comparison of therepresentation
of two SGML documents is quite different from the differences between the documents themselves and not at all useful for an author to understand what has changed. |
| | The Palimpsest data model described in
is much more sophisticated. Not only does it define a variety of basic data types for a document such as sequences, sets, or tables, it also addresses the problems of flexible merging and tracking of individual changes to a shared hypertext or multimedia document. |
| | Palimpsest describes documents entirely in terms ofdeltas
; any manipulation of a document affects only the set of deltas, not the data objects in the document state. However, the deltas that determine a document state are not ordered as a sequence of editing changes, so the information about any intermediate state during the creation process is lost. |
| |
discuss four algorithms to determine the minimal editing distance between two ordered labelled trees and propose a new algorithm that not only usesinsert
,delete
, andchange
as primitive operations, but alsoswap
,merge
,split
, andmove
. The goal of the algorithm is to determine aminimal
editing sequence, but not a difference between the documents that reflects the semantics of a change sequence performed by the author. To illustrate the difference, consider two adjacent nodes (`INTRO' left of `SECT' written as `INTRO,SECT') in a document. The author first permutes the nodes and gets `SECT,INTRO'. Then he changes the label of `INTRO' into `SECT'. The minimal editing sequence from `INTRO,SECT' to the final state `SECT,SECT' would be to just rename the `INTRO' on the left into `SECT' without performing any swapping. In case of empty nodes the transposition may not be important, but if `INTRO' or `SECT' have any content objects in their subtree, the equivalence between these unchanged content objects gets lost. |
| | The discussion above has shown that the equivalence of components in an SGML document cannot be recognized from a simple comparison of two document states. The proposed approach therefore does not compare two states to determine their differences. It rather compares a change-oriented representation of each document. Such atemporal document
reflects the evolution of its contents as it contains in form of a sequentialchange history
a description of those changes that are needed to create the document. |
| | Three problems for the development of an SGMLdiff
based on temporal documents will be addressed in this paper: what are the objects in an SGML document instance, how can we appropriately describe the changes, and how can the change history of a document be created? Last, a method is needed to compute the difference of two temporal documents. The rest of the paper is organized as follows: first the underlying model of temporal documents is introduced (section
). Section
shows how temporal documents can be used to compute a meaningful set or if needed sequence of differences and which requirements must be fulfilled. In section
, a realized prototype is described that operates on a simplified SGML document model. Section
summarizes the results and shows the direction of improvements and further development. |
| | Change-oriented view of documents |
| | The change-oriented view of a document focusses on the evolution of a document: instead of describing the actualstate
of the document it describes itschange history
. |
| | If all changes described in a temporal document can be automatically executed, its final state can always be reconstructed by an appropriate tool. The change-oriented approach of representing a document therefore leads to the same result as the traditional state-oriented concept of documents. Additionally, if a temporal document contains the description of all changes performed on it, each intermediate state, e.g. a specific version of the document's history or creation can be rebuilt. |
| | The components of a temporal document are descriptions of elementary changes that have been performed on an SGML document. These sequentially orderedchanges
describe the complete generation of the document out of an initially empty state. The changes must be elementary to guarantee an unambiguous way to describe the actions actually performed on the document. |
| | At least three types of changes exist for each type of object that may constitute an SGML document: insertion, modification, and deletion. Other elementary change types may exist that depend on the object type under consideration. As section
will show, e.g. nodes in the SGML tree that contain character data HyTimepseudo-elements
can be split in two new ones, or adjacent pseudo-elements may be joined to form a single one. Another change type may describe that an SGML element has been moved in the document from one location to another. Yet another may be defined to encode the equivalence between two SGML elements where one is a copy of the other as described in section
. |
| | The change types that constitute a temporal document must fulfil two requirements: reversibility and independence from any information in previous descriptions. Only if changes are reversible, previous states of the document can be reconstructed from its final state by performing the inverted changes of its history in reverse order. The independence of the change descriptions from any other description is required, because computing an SGMLdiff
requires a reordering and manipulation of the changes in the document's history (see
). This reordering is omly allowed if two adjacent changes in the history can be analysed and manipulated locally without any side-effects on some other change description. |
| | As a consequence, each change description must describe the component
|
| | Or the location, in case the change describes an insertion. |
| | that will be changed, relative to the document state just before that change. |
| | Creating temporal documents |
| | As discussed in
, the equivalence of objects in the documents to be compared cannot be determined by simply analysing their states. In contrast to state-oriented document models, temporal documents provide this information by descriptions of every change made to the document, particularly whether elements have been moved. Temporal documents must therefore reflect the authentic creation process of the actual document state. This can only be achieved if the used editing system protocols all editing steps actually made by the author. In addition, in order to record a useful change history of the document, the author must always use the `move' operation provided by the editing system if she actually intends to move an element. If she manually inserts an element with the same contents at the new location and then deletes the old one, the system cannot detect the `moving' of the element. |
| | If no special editing system was used and a correct tracking of equivalent elements is not a critical requirement, a temporal document may also be computed from the actual state of a document. The temporal document then contains one change of type `insert' for each component of the document's contents. |
| | Using temporal documents to build an SGMLdiff
|
| | Computing the difference between two temporal documents |
| | Temporal documents describe the evolution of their contents in an already meaningful notation. Besides, their change history is invertible, and their change history always begins with an empty document state. Therefore the difference between two temporal documents can in theory be described as the sequence of changes that would delete the first document completely, followed by all changes needed to create the second. However, as a document's history may contain as much changes as there are objects in the actual document state
|
| | At least one change of type `insert' per component is needed to generate the actual state of the document. |
| | or more, such a delta would be much too long and of no practical use. |
| | Nevertheless, such a sequence of changes contains all the information necessary for a sensible delta. What is still needed is a way to remove all irrelevant changes. With the techniques of merging and rearranging change sequences discussed in the next subsections it is possible to reduce such a delta to its minimal length, i.e. to the minimal number of changes needed to produce the second document if performed on the first one in other words the result that an SGMLdiff
shall produce. |
| | The technique to reduce a change history to its minimal length not only is needed in the context of producing an SGMLdiff
. It may also be used to reduce the length of a recorded editing session and thus the length of the temporal document which could otherwise get very big
. |
| | An author editing a document often has to correct typing mistakes or to reformulate what she just wrote. Therefore, if every editing step is recorded in a temporal document, some changes may be followed by others that are inverse to them. Such groups of changes that are inverse to each other do not describe any useful information about the evolution of the document. Because of the required independence of changes they may be removed from the temporal document without any side-effects to other parts of the change history. |
| | There are other cases where two consecutive changes can be merged: if a component has been inserted and immediately afterwards modified, it may just as well have been inserted in its modified state the two changes can be replaced by only one. Similarly, modifying or moving a document object in two successive steps can be replaced by one single change describing the entire modification or movement. The same holds for modifying an object that gets deleted afterwards: the two changes can be summarized in one that deletes the unmodified object. |
| | With merging, only two consecutive changes can be removed from a change sequence or replaced by a new change describing the same effect on the document. However, this situation will be found only in rare cases. Usually, two changes in the change history that affect the same object and that could be merged if next to each other are separated by some other changes. To merge them, the change history must be rearranged in such a way. |
| | The way to move a change in a history is to transpose it with its neighbour as often as needed to get it into the right place
,
. Transposing two consecutive changes in a history alters their order of execution. Obviously, not every pair of consecutive changes may be transposed. If the first change creates an element that is filled with some text by the following change, reversing the order of execution does not make sense. Nor is it possible to attach an attribute to a non-existing element. |
| | The transposition technique first requires a list of all the conditions that changes must fulfil to be commutative. The second task is to determine the effects of transposing commutative changes. Transposing two changes may require that the references they contain have to be modified, because these references depend on the document state affected by the change. A suitable and universal method to locate nodes in a tree is defined by the HyTimetreeloc
architectural form
that basically references nodes by their path in the document tree
|
| | A path `(1 3 2)' for example references `the second child of the third child of the root'. |
| | . So if a node is inserted by a change A, some paths in the following change B may have to be altered during transposition: after exchanging them, change B applies to the document state that existed before change A. And change A now applies to a document state that has already been modified by change B. |
| | Reducing change histories |
| | The algorithm to reduce arbitrary change histories to their minimal length is based on |
| | - rearranging the order of execution in the history to get pairs of adjacent changes and
- merging these changes, i.e. deleting them if they are inverse to each other or replacing them by a single change that describes the same effect.
|
| | A change history has been successfully reduced to its minimal length if no change is left that by repeated transpositions may be moved next to a change with which it can merge. |
| | One possible way to reduce a change history is to shift every change starting at the end of the history as far to the beginning as possible. The shifting ends either if the change cannot transpose with its new predecessor or if they merge. |
| | If the logical order of dependency that determines the rules of transposition is transitive, and if merging some changes does not influence this order
|
| | The order may be affected if the merging produces a new change for which other dependencies are defined as for the merged changes. |
| | , the history can be reduced just by analysing each change in the way described above. On the other hand, if the merging of changes produces a new dependency order, the algorithm must be refined as follows. |
| | If the shifted change does not merge with its new neighbour, both are connected to each other by references that document their logical dependency. If no merging is possible at all, the algorithm has provided each change with references to all those previous and subsequent changes with which it cannot transpose. |
| | If the changes merge, the ordering may have become locally invalid. Therefore all changes previously referenced as logically required (respectively depending) have to find their new `partners' by a repeated shifting to the beginning (respectively to the end) of the history until no further transposition is possible or until they merge. |
| | A simplified SGML document model |
| | The approach described above to build an SGMLdiff
has been implemented as part of a prototype system that demonstrates the feasibility of document engineering based on the concept of temporal documents
. Up to now four types of document objects are supported by the prototype:elements
,attributes
, HyTimepseudo-elements
in the following also calleddata objects
, and(hypertext) links
encoded as HyTime `ilinks'
. Other types like e.g. `entities' may be added. |
| | The prototype only handles document instances; it even totally ignores any information contained in the corresponding DTD
|
| | Therefore in the following the term `document' will be used in the sense of `state of an SGML document instance'. |
| | . This design decision has been made as DTDs should be designed to define the same structure for a large number of documents that may have to be compared to each other on their own without reference to the DTD they all comply to. |
| | SGML elements are regarded as labelled nodes in a hierarchical document tree. Each element carries information about its position in the tree (thereby defining the extent of the tagged textual contents) and its generic identifier. |
| | Pseudo-elements are the leaves of the document tree that contain only sequences of characters. In the prototype, entity references or the difference between e.g.CDATA
and#PCDATA
are ignored. Pseudo-elements carry information about their data content and their position in the tree (and thereby in the data stream of the document). |
| | The location of elements or pseudo-elements is described by a combination of a HyTime `treeloc' expression identifying the node in the document tree and the unambiguous name of the document encoded as a HyTime `nameloc' expression
. |
| | Attributes contain additional information the named attribute's value assigned to an element and identified by combining the identifier of the element with its unambiguous attribute name. Using the DSSSL
terminology, a document with attributes thus forms a grove rather than a tree. |
| | Finally, links are stand-alone information units that describe hypertext links from a referenced source element to a specified destination element. Links are represented as HyTime `ilinks' with a unique link name
|
| | The link name must be unique in the scope of a document's state. |
| | . Nevertheless an additional identifier is needed for a link since its name can change during the document's evolution and since this link may be referenced from another document yet unaware of the name modification. In the prototype, this ID reflects the time of creation of the link. |
| | The following list discusses each of the 15 change types implemented in the prototype. The examples use the SGML notation for change histories defined in
. Each change type is denoted by an empty element with several attributes. The meaning of the attributes is explained in the description part of the element types. |
| | Insert
,Delete
,Modify Element
. Elements having children cannot be deleted, nor canInsert Element
be used to wrap existing elements or data objects. To modify an element means to change its generic identifier (gi).
|
<ie p="(1 4 3 5 1)" gi="information" > ... <me p="(1 4 3 3 1)" ogi="information" ngi="warning" > ... <de p="(1 5 3 3 1)" gi="warning">
| | Split
,Join Data
. Before inserting an element within a pseudo-element (`mixed content'), the latter must be split into two parts. Conversely, after deleting an element surrounded by data, the remaining two adjacent pseudo-elements have to be joined to form a single data node in the document tree. To describe this change completely the length (l1, l2) of each fragment must be given next to its path (p1, p2).
|
<join p1="(1 4 5 3 1)" l1="40" p2="(1 4 5 3 2)" l2="30"> ... <split p1="(1 4 3 3 1)" l1="6" p2="(1 4 3 3 2)" l2="63">
| | Insert
,Delete Data
. In contrast to elements, the contents of a data object cannot be modified, as pseudo-elements may lose their identity in the document tree when split or joined.
|
<id p="(1 4 3 5 1 1 1)">CONF:CR, OPSTAT=INACT;</id> ... <dd p="(1 4 5 7 2 1 1)">CONF:CR, OPSTAT=INACT;</dd>
| | Insert
,Delete
,Modify Attribute
. As each change description must be invertible, aModify Attribute
must not only contain the new name and value (nan, nav), but also their old values (oan, oav).
NOTE:
The same holds for the generic identifier inModify Element
as illustrated in the example above.
|
<ia p="(1 1 4 1 1)" an="entity" av="tab-4.2.gif"> ... <ma p="(1 10 4 4 2)" oan="entity" nan="entity" oav="tab-4.2.gif" nav="tab-4.1.gif"> ... <da p="(1 8 4 10 1)" an="entity" av="tab-4.1.gif">
| | Insert
,Delete
,Modify Link
. If a link is created, the information about this change is documented in all affected documents, i.e. in the documents which contain the source (lsd), the destination (ldd), and the link itself (ld). The link is referenced by its name (ln) and its time of creation (lt). A link must be modified if e.g. a path to one of the referenced elements (lsp, ldp) has changed in a different document than the one which contains the link.
|
<il ld="linkbase.sgml" lt="(12923 53988 40215)" ln="Mark2Tabchap4-1" lsd="ewsd.sgml" lsp= "(1 8 4 4 6 2 4 2 2)" ldd="d900.sgml" ldp="(1 10 4)"> ... <ml ld="linkbase.sgml" lt="(12923 53988 40215)" oln="Mark2Tabchap4-1" nln="Mark2Tabchap4-1" olsd="ewsd.sgml" olsp= "(1 8 4 4 6 2 4 2 2)" nlsd="ewsd.sgml" nlsp= "(1 8 4 4 6 2 10 2 2)" oldd="d900.sgml" oldp="(1 10 4)" nldd="d900.sgml" nldp="(1 10 4)"> ... <dl ld="linkbase.sgml" lt="(12923 53988 40215)" ln="SeeTabChap4-1" lsd="ewsd.sgml" lsp= "(1 5 3 4 9 2 2 2 2)" ldd="d900.sgml" ldp="(1 5 4)">
| | Equal
,Diff
. A change of typeEqual
documents an equivalence relation between the element that it applies to and another one that has also been `touched' by anEqual
with the same ID (t).Equal
does not actually change the document state, it only freezes the element touched (with path p in the document d) in its actual state. Finally,Diff
is needed as the inverse type ofEqual
.
|
<equal t="(12090 33686 399015)" p="(1 4 3)" d="ewsd.sgml"> ... <diff t="(12090 33686 399015)" p="(1 4 5)" d="ewsd.sgml">
| | This change type is used for three complex changes:Copy
,Move
, andFreeze
(as a version). Copying an element is actually a sequence of elementary changes: first, the element is copied in a buffer (documented by anEqual
), then the copy is inserted at the intended location, possibly after some other changes have been executed in between. Because changes have to be independent of any information connected to previous changes (see
), the copy cannot be inserteden bloc
. Instead, each single step that built up the first element must also be performed to build up the copy. Only then, a secondEqual
applied to the new copy documents the equivalence between both elements.
Moving an element is documented in much the same way, only followed by a sequence of changes that delete the copied element. The third usage forEqual
is to freeze an element (usually the root element) in its actual state and give this new version a name. A change of typeDiff
can later be used to delete this version.
|
| | The change types described above fulfil the requirement of invertibility: anInsert
is the inverse of aDelete
, inverting aModify
implies exchanging the old and the new values,Diff
is the opposite ofEqual
, and a change of typeSplit
may be used to eliminate the effect of aJoin
. The inverse of asequence
of changes is obtained by aligning the inverse of each change in reverse order. |
| | Rules for merging changes |
| | Section
already described most of the rules for merging adjacent changes implemented in the prototype. As an example, consider the following situation. First an element `information' is inserted as the second child of an element with the path `(1 3 2)'. Thereafter its generic identifier is changed into `warning': |
... <ie p="(1 3 2 1)" gi="information"> <me p="(1 3 2 1)" ogi="information" ngi="warning"> ...
| | The single change<ie p="(1 3 2 1)" gi="warning">
describes the same effect. It can replace the two changes above, because any other change of the history is independent of them (as required in section
) and because the states of the document before and after them remain the same, so that all references in subsequent changes are not affected by an exchange. |
| | In addition to the general rule that inverse changes may be taken out of the history, other merging rules hold for changes likeJoin
,Split
, orEqual
. For example. it is useless to freeze an element twice with two changes of typeEqual
that use the same name; freezing it once has the same effect. |
| | Changes of typeSplit
(Join
) produce (require) a document state with two adjacent data objects, a situation that is in conflict to the HyTime definition of a pseudo-element. However, in some cases these changes are needed to prepare (finish) a subsequent (previous) change. The following merging rules involvingthree
consecutive changes reflect this close relationship between aSplit
orJoin
and some connected change: |
| | Inserting two data objects that are joined in a third step like in <id p="(1 4 3 5 1)">CONF:CR, </id> <id p="(1 4 3 5 2)">OPSTAT=INACT;</id> <join p1="(1 4 3 5 1)" l1="9" p2="(1 4 3 5 2)" l2="13">
is the same as inserting the concatenated string in one single change:<id p="(1 4 3 5 1)">CONF:CR, OPSTAT=INACT;</id>
|
| | Similarly, splitting a data object in two parts that are deleted afterwards <split p1="(1 4 3 5 1)" l1="9" p2="(1 4 3 5 2)" l2="13"> <dd p="(1 4 3 5 1)">CONF:CR, </dd> <dd p="(1 4 3 5 1)">OPSTAT=INACT;</dd>
is the same as deleting it in only one step:<dd p="(1 4 3 5 1)">CONF:CR, OPSTAT=INACT;</id>
|
| | Rules for transposing changes |
| | As discussed in
, not every tuple of changes may be transposed. In the prototype, a logical dependency between two changes is given if the second change in a particular document state `touches' an object or a location, that is the result of the first change. An example for this is an element that is first inserted and then deleted. |
| | Less intuitive is the situation where the first change deletes an element and thereby `creates' a `location' which is then touched by the second change that inserts an object at exactly the same place. In this situation, it is not possible to transpose the changes in an unambiguous way: no information is given to determine if the object that is deleted after the insertion shall be a righthand or a lefthand neighbour of the object that has been created first. |
| | If two changes are not logically dependent they can be transposed. To do so, all references in the changes must be appropriately adjusted as in the following example. Transposing <de p="(1 4 3 5 2)" gi="notice"> <dd p="(1 4 3 5 1)">OPSTAT=INACT;</dd>
results in<dd p="(1 4 3 5 1)">OPSTAT=INACT;</dd> <de p="(1 4 3 5 1)" gi="notice">
|
| | There are special rules for transposing changes of typeSplit
andJoin
, because they also specify the length of the fragments involved. For example, a succeedingSplit
depends logically on a preceedingJoin
only if the string shall be split at the same point where it has been joined before, i.e. if they are inverse to each other. If not, they may very well be transposed, as a closer look at the next example shows: ... <id p="(1 4 3 5 1)">CONF:CR, </id> <id p="(1 4 3 5 2)">OPSTAT=INACT;</id> <join p1="(1 4 3 5 1)" l1="9" p2="(1 4 3 5 2)" l2="13"> <split p1="(1 4 3 5 1)" l1="16" p2="(1 4 3 5 2)" l2="6"> <dd p="(1 4 3 5 1)">CONF:CR, OPSTAT=</dd> <dd p="(1 4 3 5 1)">INACT;</dd> ...
Transposing the third and fourth change results in:... <id p="(1 4 3 5 1)">CONF:CR, </id> <id p="(1 4 3 5 2)">OPSTAT=INACT;</id> <split p1="(1 4 3 5 2)" l1="7" p2="(1 4 3 5 3)" l2="6"> <join p1="(1 4 3 5 1)" l1="9" p2="(1 4 3 5 2)" l2="7"> <dd p="(1 4 3 5 1)">CONF:CR, OPSTAT=</dd> <dd p="(1 4 3 5 1)">INACT;</dd> ...
Finally, if an element's state is fixed by a change of typeEqual
, no change that affects this state can be transposed with theEqual
. Consider e.g. anEqual
that freezes the root element followed by a change that inserts a new child of the root. If these changes are transposed, the child would be inserted first and then a new anddifferent
state of the root would be fixed. |
| | Given two temporal documents, the SGMLdiff
is basically computed as described in section
. First, the change history of the first document is inverted. Then the history of the second document is appended to it, resulting in a long change history that transforms the last state of the first document into the final state of the second. This delta history is then reduced to its minimal length. In a first step though, all existing pairs of inverse changes with typeEqual
andDiff
are taken out of the delta, as it is usually not possible to bring them next to each other by repeated transpositions. Afterwards the delta is reduced following the algorithm described in
. |
| | This contribution has presented an approach to build an SGMLdiff
. It is based on a change-oriented model for structured documents. Contrary to the traditional approach of storing thestate
of a document, temporal documents contain achange history
that describes how to create the actual document state out of an initially empty state. |
| | The basic idea for building an SGMLdiff
is to use the information already contained in temporal documents. To compute a meaningful delta, first a long delta history is created by concatenating the inverted change history of the first document resulting in the empty state and the history of the second document starting with the empty state. This delta history then is reduced to a minimal length by merging subsequent changes that are brought together by repeated transpositions. |
| | The feasibility of the proposed method has been demonstrated by a prototype based on a very simple model for structured documents that defines the types `element', `attribute', `pseudo-element', and `link' for the objects forming a document state. Though the prototype does not support the full complexity of the SGML document model, the method described is not restricted to the object types chosen for the prototype. New object types may be added together with appropriate change types. These new change types must be invertible, and conditions and rules have to be defined that describe their merging and transposing with consecutive changes. |
| | Finally, the delta obtained by such an SGMLdiff
must be visualized. Just listing the sequence of change descriptions in some particular notation is not the appropriate way. One possibility (realized in
) is to display two states of the document for comparison that may be randomly chosen from the delta. As the change history between the displayed states contains all necessary information about the evolution of each object in the document, the differences between the two states can be visualized as desired. |
| | [BCD95]
Barnard, D.T., Clarke, G., Duncan, N.Tree-to-tree Correction for Document Trees.
Technical Report 95-372, Dep. of Computing and Information Science, Queen's University, Kingston, Ontario, Canada (1/1995), http:// www.qucis.queensu.ca/ TechReports/ Reports/ 95-372.ps.
|
| | [DD94]
S. J. DeRose, D. G. Durand.Making Hypermedia Work A User's Guide to HyTime
Kluwer Academic Publishers (1994).
|
| | [Dur94]
D. G. Durand.Palimpsest: A Data Model for Revision Control.
Proc. of the CSCW 94 Workshop on Collaborative Hypermedia Systems, GMD, (1994) GMD Studien Nr. 239.
|
| | [ISO96]
DIS 10179: Information technology Text and office systems Document Style Semantics and Specifikation Language (DSSSL)
, ISO/IEC (1996).
|
| | [RTW96]
D. Raymond, F. Tompa, D. Wood.From data representation to data model: Meta-semantic issues in the evolution of SGML.
Computer Standars & Interfaces 18 (1996) 25-36.
|
| | [Mφl97]
H. Mφller.Konsistentes Dokumentenengineering mit temporalen Dokumenten.
PhD-Thesis (1997), forthcoming.
|
| | [PKa92]
A. Prakash, M.J. Knister.Undoing Actions in Collaborative Work.
Proc. CSCW 92, ACM (1992).
|
| | [PKb92]
A. Prakash, M.J. Knister.Undoing Actions in Collaborative Work.
Report CSE-TR-125-92, Dep. of Electr. Engin. and Comp. Sci., Univ. of Michigan (1992).
|