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>
        <b fxd:unwrap="">unwrapping</b> 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

Text additions

<fxd:text-addition />

Is wrapped around the added text.

Text deletions

<fxd:text-deletion />

Is wrapped around the deleted text.

Element additions

attribute: @fxd:addition=""

Is added to the new element.

Element deletions

attribute: @fxd:deletion=""

Is added to the removed element.

Wraps

attribute: @fxd:wrap=""

Is added to the new element that is wrapping content.

Unwraps

attribute: @fxd:unwrap=""

Is added to the unwrapped element.

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 (for containers & blocks)

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

The tombstone element is placed at the old location. The attribute is added to the moved element (at its new location). The value of the 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

Text additions

Text insertions are wrapped within an <fxd:text-addition /> element.

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


Text deletions

Text deletions are wrapped within an <fxd:text-deletion /> element. 

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


Element additions

New elements will have the @fxd:addition attribute. This indicates that the element and its descendants are new.

<p xmlns:fxd="http://schemas.fontoxml.com/document-history/1.0/differences.xsd">
    We are adding <b fxd:addition="">new <i>elements</i></b>
</p>


Element deletions

Elements that are deleted will have the @fxd:deletion attribute. This indicates that the element and its descendants are removed. 

<p xmlns:fxd="http://schemas.fontoxml.com/document-history/1.0/differences.xsd">
    We are removing <b fxd:deletion="">these <i>elements</i></b>
</p>


Wraps

When a wrap occurs (e.g. wrapping some existing text in a <b/> element), the newly created element will be annotated with the @fxd:wrap attribute to indicate that this element is wrapping existing content. The value of the attribute will always be empty and thus has no further meaning. 

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


Unwraps

When an unwrap occurs (e.g. unwrapping some text in a <b/>), the unwrapped element will be annotated with the @fxd:unwrap attribute to indicate that this element was unwrapped and doesn’t exist anymore. The content of the unwrapped element will still exist. The value of the attribute will always be empty and thus has no further meaning.

<p xmlns:fxd="http://schemas.fontoxml.com/document-history/1.0/differences.xsd">
    We are 
    <b fxd:unwrap="">unwrapping</b>
    text
</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

A move can only occur for containers and blocks. An <fxd:moveTombstone/> is left behind at the old position. It holds a reference to the new location using the @fxd:moveIdRef attribute. The container or block is placed at its new location and now holds 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>
        <p fxd:moveId="0">some text</p>
    </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?