Diff API

The Diff API can be used to compare two documents. The result is an annotated version of the base document which contains instructions to transform the document into the other document. A common use-case for this API is to produce assist in producing a redlined/blacklined document.

Request specification

POST /api/diff

This API is offered by the Document History back-end application.


Headers:

Header Value
Content-Type multipart/form-data

Body:

Parameter

Required

Type

Description

a

Required

File (multipart/form-data)

Holds XML document “a”.

b

Required

File (multipart/form-data)

Holds XML document “b”.

Responses

Status Reason and model
200 OK

Returned when a valid diff is produced.

Headers:

Header Value
Content-Type application/xml
Content-Disposition attachment; filename=result.xml

Body: The body contains the XML of the diff result.

400 Bad Request

Returned when one of the required parameters is missing or invalid XML is received.

Headers:

Header Value
Content-Type
application/problem+json

Body: The body contains a serialized error as described here: https://docs.microsoft.com/en-us/aspnet/core/web-api/?view=aspnetcore-3.1#default-badrequest-response

Logs containing additional details will be present in the Fonto Document History back-end application.

500 Internal Server Error

Returned when an unexpected error occurs in the diff service. 

Headers:

Header Value
Content-Type
application/problem+json

Body: The body contains a serialized error as described here: https://docs.microsoft.com/en-us/aspnet/core/web-api/?view=aspnetcore-3.1#default-badrequest-response

Logs containing additional details will be present in the Fonto Document History back-end application.


Examples

Response

  Minimal request
file 'a'
<div>
    <p><b>unwrapping</b> the bold element.</p>
</div>
file 'b'
<div>
    <p>unwrapping the bold element.</p>
</div>
  Minimal response
<?xml version="1.0" encoding="utf-8"?>
<div xmlns:fxd="http://schemas.fontoxml.com/document-history/1.0/differences.xsd">
    <p>
        <fxd:unwrap><b>unwrapping</b></fxd:unwrap> the bold element.
    </p>
</div>


Diff result

This API returns an annotated version of document a that translates to document b. This is called the diff result. It contains the XML of the document a together with annotations that explain how the document is transformed to document b. The annotations consist of elements and attributes that are being used to annotate the document. The annotations are contained within a separate namespace, for which the declaration is added to the root element of the diff result:

xmlns:fxd="http://schemas.fontoxml.com/document-history/1.0/differences.xsd"

None of the element- or attribute annotations (recognizable by the fxd namespace) were ever present in the a or b version; They are used to explain the differences and are only part of the API response body.

Annotations

A summary of the annotations that are used in the diff result.

Annotation

Expressed by

Description

Additions

<fxd:addition />

Is wrapped around the addition.

Deletions

<fxd:deletion />

Is wrapped around the deletion.

Wraps

<fxd:wrap />

Is wrapped around the element that is wrapping existing content.

Unwraps

<fxd:unwrap />

Is wrapped around the element that is being unwrapped.

Object replacements

<fxd:replacement/>

Is wrapped around a modified object. It will contain the old object*1 and new object*2.

Structural table changes <fxd:replacement/> Is wrapped around a structurally changed table. It will contain the old object*1 and new object*2.

*1 Old object (only within a replacement)

<fxd:old />

Is wrapped around the old version of the object.

*2 New object (only within a replacement)

<fxd:new />

Is wrapped around the new version of the object.

Moves

<fxd:moveTombstone fxd:moveIdRef="0" /> and <fxd: move fxd:moveId="0" />

The <fxd:moveTombstone /> element is placed at the old location. The <fxd:move /> element is added around the moved content (at its new location). The value of the @fxd:moveId attribute uniquely refers to the appropriate tombstone.

Attribute changes

<fxd:attributes>

Attribute changes are annotated within the element of the changed attribute and grouped in the fxd:attributes element. It holds the individual attribute changes.

Attribute addition

<fxd:attribute-addition fxd:ns="" fxd:localName="" fxd:value=""/>

Is used to represent a new attribute. 

Attribute deleted

<fxd:attribute-deletion fxd:ns="" fxd:localName=""/>

Is used to represent a deleted attribute.

Attribute value replacement

<fdx:attribute-change fxd:ns="" fxd:localName="" fxd:value=""/>

Is used to represent a value change of an existing attribute.

Examples

Additions

Additions are wrapped within an <fxd:addition /> element.

<p xmlns:fxd="http://schemas.fontoxml.com/document-history/1.0/differences.xsd">
	We are adding <fxd:addition>some</fxd:addition> text <fxd:addition><b>and an element</b></fxd:addition>
</p>


Deletions

Deletions are wrapped within an <fxd:deletion /> element. 

<p xmlns:fxd="http://schemas.fontoxml.com/document-history/1.0/differences.xsd">
    We are removing <fxd:deletion>some</fxd:deletion> text <fxd:deletion><b>and an element</b></fxd:deletion>
</p>


Wraps

When a wrap occurs (e.g. wrapping some existing text in a <b/> element), the newly created element will be wrapped within an <fxd:wrap /> element to indicate that this element is wrapping existing content. 

<p xmlns:fxd="http://schemas.fontoxml.com/document-history/1.0/differences.xsd">
    We are <fxd:wrap><b>wrapping</b></fxd:wrap> text
</p>


Unwraps

When an unwrap occurs (e.g. unwrapping a <b/> element), the unwrapped element will be wrapped within ane <fxd:unwrap /> element to indicate that its child element needs to be unwrapped and doesn’t exist anymore. The content of the unwrapped element will still exist.

<p xmlns:fxd="http://schemas.fontoxml.com/document-history/1.0/differences.xsd">
    We are <fxd:unwrap><b>unwrapping</b></fxd:unwrap> an element
</p>


Object replacements

A replacement occurs when an object is modified (e.g. a change of attributes or any other change within the element). An element is an object when it is configured as such in Document History. The replacement is wrapped with the <fxd:replacement/> element. The old version of the object will be marked as old using the <fxd:old/> element and the new version of the object is marked as new using the <fxd:new/> element.

Note that an object can be replaced and moved at the same time. In that case the <fxd:replacement/> element will also have the @fxd:moveIdRef attribute. See the "Moves" example for more information on moves.

<p xmlns:fxd="http://schemas.fontoxml.com/document-history/1.0/differences.xsd">
    <fxd:replacement>
        <fxd:old>
            <mathml>A</mathml>
        </fxd:old>
        <fxd:new>
            <mathml>B</mathml>
        </fxd:new>
    </fxd:replacement>
</p>


Structural table changes

A structural table change is defined as adding/deleting rows, adding/deleting columns, merging/splitting cells or making attribute changes to an of the elements that make up the structure of the table. This does not include changes within a cell of a table. When a structural change is detected, both the old table and the new table are provided and wrapped in a <fxd:replacement/> element.

<div xmlns:fxd="http://schemas.fontoxml.com/document-history/1.0/differences.xsd">
    <fxd:replacement>
        <fxd:old>
            <table>
                <tr>
                    <td>A</td>
                    <td>B</td>
                </tr>
                <tr>
                    <td>C</td>
                    <td>D</td>
                </tr>
            </table>
        </fxd:old>
        <fxd:new>
            <table>
                <tr>
                    <td>A</td>
                    <td>B</td>
                </tr>
                <tr>
                    <td>C</td>
                    <td>D</td>
                </tr>
				<!-- This row is inserted -->
                <tr>
                    <td>NEW</td>
                    <td>NEW</td>
                </tr>
            </table>
        </fxd:new>
    </fxd:replacement>
</div>


Moves

An <fxd:moveTombstone /> is left behind at the old position. It holds a reference to the new location using the @fxd:moveIdRef attribute. The moved content is placed at its new location and is now wrapped within an <fxd:move /> element that has an @fxd:moveId attribute that refers to the old location (tombstone). Nested changes in moved content are embedded within the moved element just like ordinary changes.

<div xmlns:fxd="http://schemas.fontoxml.com/document-history/1.0/differences.xsd">
    <fxd:moveTombstone fxd:moveIdRef="0" />
    <div>
		<fxd:move fxd:moveId="0"><p>some text</p></fxd:move>
    </div>
</div>


Attribute changes

When attributes change, an <fxd:attributes/> element is added to the element that contains the attribute changes. 

For every attribute value that changed, an <fxd:attribute-change /> element is used. For every attribute that is added, an <fxd:attribute-addition /> element is used and has an @fxd:value attribute that holds the value of the attribute. For every attribute that is removed, an <fxd:attribute-deletion /> element is used.

All three attribute elements (<fxd:attribute-change />, <fxd:attribute-addition /> and <fxd:attribute-deletion />) also have the attributes @fxd:ns (holds the attribute namespace) and @fxd:localName (holds the attribute name). 

<div xmlns:fxd="http://schemas.fontoxml.com/document-history/1.0/differences.xsd">
    <p class="info">
        <fxd:attributes>

            <fxd:attribute-addition fxd:ns="" fxd:localName="my-new-attribute" fxd:value="my-new-attribute-value"/>

            <fxd:attribute-deletion fxd:ns="" fxd:localName="class"/>

            <fxd:attribute-change fxd:ns="" fxd:localName="class" fxd:value="warning" />

        </fxd:attributes>
    </p>
</div>
Was this page helpful?