Loading login details...

Configuring DeltaXML to Handle Timestamps

Note: While the techniques presented in this document will still work, a new general-purpose system for ignoring change was introduced in the DeltaXML Core 5.1 release.  Please now refer to the How to ignore changes document and samples in the 5.1 release instead of this document.

When comparing two documents you may wish to ignore a change in a "timestamp" attribute, so that a timestamp-only change is not reported, but a more significant change is reported along with the old and new timestamp values.

Though we concentrate here on timestamps, since they provide a simple example, this technique can be used to ignore any attributes while reporting the original values.

Where you do not need to see the old and new timestamp values, a simpler approach can be adopted, removing the 'ignorable' item altogether - for details please see Configuring DeltaXML To Ignore Elements.

We start with a specific example. We have two files to compare, as shown below.

<?xml version="1.0"?> 
<top> 
 <a timestamp="2003-09-22.20:50:48">Content of a</a> 
 <b timestamp="2003-09-22.20:50:48">Content of b</b> 
 <c timestamp="2003-09-22.20:50:48">Content of c</c> 
 <d timestamp="2003-09-22.20:50:48">Content of d</d> 
</top>

and

<?xml version="1.0"?> 
<top> 
 <a timestamp="2003-09-22.20:50:48">Content of a</a> 
 <b timestamp="2003-09-31.20:46:03">Content of b</b> 
 <c timestamp="2003-09-31.20:46:03">Content of c!</c> 
 <d timestamp="2003-09-31.20:46:03">Content of d</d> 
</top>

In this example, element <a> is the same in both files. The other elements all have different timestamp attributes in the second file. Element <b> and element <d> have no change to their data, whereas element <c> has a change. Therefore we do not want to see changes reported for any elements except for <c>.

To achieve this, we first compare the two files as they are, and generate a full context delta, i.e. a delta file which includes the changes and the unchanged data all in a single XML file. This produces the following file

(Note particularly the old-attributes and new-attributes values, which contain the timestamp information with the quotation marks escaped as &quot;)

<top xmlns:deltaxml="http://www.deltaxml.com/ns/well-formed-delta-v1" 
 xmlns:dxa="http://www.deltaxml.com/ns/non-namespaced-attribute"
 deltaxml:deltaV2="A!=B" deltaxml:version="2.0" deltaxml:content-type="full-context">
 <a deltaxml:deltaV2="A=B" timestamp="2003-09-22.20:50:48">Content of a</a>
 <b deltaxml:deltaV2="A!=B"> 
  <deltaxml:attributes deltaxml:deltaV2="A!=B">
   <dxa:timestamp deltaxml:deltaV2="A!=B">
    <deltaxml:attributeValue deltaxml:deltaV2="A">
     2003-09-22.20:50:48
    </deltaxml:attributeValue>
    <deltaxml:attributeValue deltaxml:deltaV2="B">
     2003-09-31.20:46:03
    </deltaxml:attributeValue>
   </dxa:timestamp>
  </deltaxml:attributes>
  Content of b</b> 
 <c deltaxml:deltaV2="A!=B">
  <deltaxml:attributes deltaxml:deltaV2="A!=B">
   <dxa:timestamp deltaxml:deltaV2="A!=B">
    <deltaxml:attributeValue deltaxml:deltaV2="A">
     2003-09-22.20:50:48
    </deltaxml:attributeValue>
    <deltaxml:attributeValue deltaxml:deltaV2="B">
     2003-09-31.20:46:03
    </deltaxml:attributeValue>
   </dxa:timestamp>
  </deltaxml:attributes>
  <deltaxml:textGroup deltaxml:deltaV2="A!=B">
   <deltaxml:text deltaxml:deltaV2="A">
    Content of c
   </deltaxml:text>
   <deltaxml:text deltaxml:deltaV2="B">
    Content of c!
   </deltaxml:text>
  </deltaxml:textGroup>
 </c>
 <d deltaxml:deltaV2="A!=B">
  <deltaxml:attributes deltaxml:deltaV2="A!=B">
   <dxa:timestamp deltaxml:deltaV2="A!=B">
    <deltaxml:attributeValue deltaxml:deltaV2="A">
     2003-09-22.20:50:48
    </deltaxml:attributeValue>
    <deltaxml:attributeValue deltaxml:deltaV2="B">
     2003-09-31.20:46:03
    </deltaxml:attributeValue>
   </dxa:timestamp>
  </deltaxml:attributes>
  Content of d
 </d>
</top>

It is straightforward to generate, from a full context delta, either of the original files. In this case, what we will do is to generate the original files - but including any timestamp changes. For example, for element <b> we will generate a timestamp attribute:

timestamp="2003-09-22.20:50:48|2003-09-31.20:46:03"

We have chosen to use the slash symbol, "/", to separate the two values.

Now we can compare these two files and there will be no differences generated by timestamp changes. The full context delta that results is as follows:

<top deltaxml:deltaV2="A!=B" deltaxml:version="2.0" deltaxml:content-type="full-context">
 <a deltaxml:deltaV2="A=B" timestamp="2003-09-22.20:50:48">Content of a</a> <b deltaxml:deltaV2="A=B" timestamp="2003-09-22.20:50:48/2003-09-31.20:46:03">Content of b</b> 
 <c deltaxml:deltaV2="A!=B" timestamp="2003-09-22.20:50:48/2003-09-31.20:46:03">
  <deltaxml:textGroup deltaxml:deltaV2="A!=B">
   <deltaxml:text deltaxml:deltaV2="A">
    Content of c
   </deltaxml:text>
   <deltaxml:text deltaxml:deltaV2="B">
    Content of c!
   </deltaxml:text>
  </deltaxml:textGroup>
 </c>
 <d deltaxml:deltaV2="A=B" timestamp="2003-09-22.20:50:48/2003-09-31.20:46:03">
  Content of d
 </d>
</top>

In this case, the only change noted is the one where there is a 'real' change, i.e. element <c>. It is certainly possible to go one stage further and display the change to the timestamp in this case in a special way.

This approach is easily extended. For example, the timestamp attribute can be replaced by two attributes: old-timestamp and new-timestamp, and the original values stored in these. In this case, for element <b> we would get two attributes in each of the files:

old-timestamp="2003-09-22.20:50:48" new-timestamp="2003-09-31.20:46:03"

The result would be the same: changes detected solely from a changed timestamp would be ignored. A different namespace could also be used in these cases.

This provides a simple and versatile mechanism for ignoring specific attributes when detecting changes while preserving the original values for display.

Ignoring timestamp elements

A similar principle can be applied to elements that contain timestamps. Any element which needs to be ignored should appear in both files as the old and new values. For example, if we had a <timestamp> element in both files, we could generate either:

<old-timestamp>...</old-timestamp> <new-timestamp>...</new-timestamp>

or perhaps:

<dual-timestamp> <timestamp>...</timestamp> <timestamp>...</timestamp> </dual-timestamp>

In the same way as with the attributes, changes due solely to changed <timestamp> elements will be disregarded.

If you have more sophisticated requirements, we can advise on best practices and supply sample XSLT code - please contact us for details.