When you compare two Word files and the only difference is how a list is numbered, say clauses that were 1. and 2. are now a. and b., or a numbered list has become a bulleted one, Aspose.Words reports no differences by default. This tutorial shows you how to detect numbering changes when comparing Word files in Python. It also explains how to review, accept, or reject the changes it finds.
Key Takeaways
- By default, a change to a list’s numbering style or bullet character produces no revisions when you compare Word files.
- Setting
options.advanced_options.compare_list_definitions = Truereports each affected list paragraph as aFORMAT_CHANGErevision. - Text changes inside list items are reported either way. The option only adds numbering and bullet changes on top.
ignore_formatting=Truehides numbering changes even when the option is on.
Why Numbering Changes Don’t Show Up by Default
Numbering and bullets in Word come from a list definition. It describes how each list level looks: the number style (1., a., i.), the bullet character, and related formatting. When you compare documents, Aspose.Words follows Microsoft Word by default and leaves list definitions out of the comparison. So if only the numbering changed, the comparison sees nothing to report.
The compare_list_definitions option has no equivalent in Word. It tells Aspose.Words to include list definitions in the comparison. Here is what we saw when comparing two-item lists in version 26.9:
| Original list | Edited list | Option off | Option on |
|---|---|---|---|
Numbered 1. 2. | Bulleted | 0 revisions | 2 FORMAT_CHANGE |
Numbered 1. 2. | Lettered a. b. | 0 revisions | 2 FORMAT_CHANGE |
| Numbered, “Item 2” | Bulleted, “Item two” | 2 (DELETION, INSERTION) | 4 (adds 2 FORMAT_CHANGE) |
| Numbered | Identical numbered list | 0 revisions | 0 revisions |
The last row matters in practice. Turning the option on does not create extra revisions for lists that are the same in both files.
Prerequisites
You need Aspose.Words for Python via .NET 26.9 or later. Install or upgrade it from PyPI:
pip install --upgrade "aspose-words>=26.9"
Without a license, Aspose.Words runs in evaluation mode with limitations. A temporary license removes them while you test.
See the Difference: Numbering Changes With and Without the Option
The following script builds two documents that contain the same two items. The first uses a numbered list, and the second uses a bulleted list. It compares them twice, once with the option off and once with it on, so you can see exactly what the option changes.
import datetime
import aspose.words as aw
def build_list_document(bulleted: bool) -> aw.Document:
"""Create a two-item list, either numbered or bulleted."""
doc = aw.Document()
builder = aw.DocumentBuilder(doc=doc)
if bulleted:
builder.list_format.apply_bullet_default()
else:
builder.list_format.apply_number_default()
builder.writeln("Item 1")
builder.writeln("Item 2")
builder.list_format.remove_numbers()
return doc
def compare_lists(compare_list_definitions: bool) -> aw.Document:
original = build_list_document(bulleted=False)
edited = build_list_document(bulleted=True)
options = aw.comparing.CompareOptions()
options.advanced_options.compare_list_definitions = compare_list_definitions
# compare() writes revisions into `original`; it returns nothing.
original.compare(
document=edited,
author="Reviewer",
date_time=datetime.datetime.now(),
options=options,
)
return original
for flag in (False, True):
result = compare_lists(flag)
print(f"compare_list_definitions={flag}: {result.revisions.count} revision(s)")
for revision in result.revisions:
revision_type = aw.RevisionType(revision.revision_type).name
text = revision.parent_node.get_text().strip()
print(f" {revision_type}: {text}")
result.save("compared-lists.docx")
Running the script prints:
compare_list_definitions=False: 0 revision(s)
compare_list_definitions=True: 2 revision(s)
FORMAT_CHANGE: Item 1
FORMAT_CHANGE: Item 2
How the Code Works
build_list_documentusesDocumentBuilder.list_formatto start a default numbered or bulleted list, writes two items, and then callsremove_numbers()so any later paragraphs are not part of the list.CompareOptions.advanced_optionsexposescompare_list_definitions, which defaults toFalse.original.compare(...)comparesoriginalagainsteditedand records the differences as revisions insideoriginal. The method returnsNone, so always read the results from the document you called it on.- Each revision’s
parent_nodeis the list paragraph whose formatting changed.revision_typeisRevisionType.FORMAT_CHANGEfor numbering and bullet changes.
Detect Numbering Changes Between Two Word Files
In a real workflow, you compare two existing files, such as two versions of a contract. Those comparisons usually contain other revisions too, so the script below keeps only the formatting changes that sit on list paragraphs.
import datetime
import aspose.words as aw
original = aw.Document("contract-v1.docx")
edited = aw.Document("contract-v2.docx")
options = aw.comparing.CompareOptions()
options.advanced_options.compare_list_definitions = True
original.compare(edited, "Reviewer", datetime.datetime.now(), options)
# Keep only formatting revisions that sit on list paragraphs.
list_changes = [
rev for rev in original.revisions
if rev.revision_type == aw.RevisionType.FORMAT_CHANGE
and rev.parent_node is not None
and rev.parent_node.node_type == aw.NodeType.PARAGRAPH
and rev.parent_node.as_paragraph().list_format.is_list_item
]
print(f"Total revisions: {original.revisions.count}")
print(f"Formatting changes on list paragraphs: {len(list_changes)}")
for rev in list_changes:
print(f" {rev.parent_node.get_text().strip()}")
original.save("contract-compared.docx")
In our test, version 2 of the contract changed a numbered list to bullets and also made an unrelated sentence bold. The output was:
Total revisions: 5
Formatting changes on list paragraphs: 2
Invoices are due in 30 days.
Late fees apply after 45 days.
The filter picks out the two list items and skips the bold change, because that revision sits on text rather than on a list paragraph. Keep in mind that it matches any paragraph-level formatting change on a list item, such as a changed indent, not only numbering. Check the saved document if you need to tell those apart.
Review, Accept, or Reject Numbering Changes
Because numbering changes are ordinary format revisions, you handle them the same way as any other revision:
revisions.accept_all()applies the edited list formatting. In the first example, both items become bullets.revisions.reject_all()keeps the original formatting, so the items stay numbered1.and2..- Saving the document writes the revisions as tracked changes, so reviewers can open the file in Microsoft Word and decide on each change themselves.
You can also call accept() or reject() on individual Revision objects, for example on only the items in the list_changes list from the previous section.
When to Detect Numbering Changes
Turn the option on when the numbering of a list carries meaning for your reviewers. Legal and policy documents are a common case: renumbering clauses from 1. to (a) changes how other documents refer to them, so a reviewer needs to see it. It is also useful when you migrate documents between systems and want to confirm that list numbering survived the move unchanged.
Leave it off when you only care about wording. Content reviews, translation checks, and text-level diffs are easier to read without formatting revisions mixed in.
Things to Watch For
ignore_formattingoverrides the option. If you setoptions.ignore_formatting = True, numbering changes are not reported, even withcompare_list_definitions = True.- Files must not contain revisions before you compare them. If either document already has tracked changes,
compareraises aRuntimeErrorsaying that compared documents must not have revisions. Accept or reject existing revisions first. This also means you can’t run a second comparison on a document that already holds the results of the first; reload the files each time. - Other revisions still appear. Inserted or deleted text in a list item is reported whether the option is on or off, so check
revision_typeif you need to separate numbering changes from wording changes.
Next Steps
The Compare Documents article in the Aspose.Words for Python documentation covers the other comparison settings, including granularity, the comparison target, and the ignore options.
FAQs
Why doesn’t Aspose.Words detect numbering changes when comparing Word files? By default, Aspose.Words follows Microsoft Word and leaves list definitions, such as the numbering style or bullet character, out of the comparison. A list that changes from numbers to bullets produces no revisions unless you enable
compare_list_definitions.How do I detect numbering changes in Python? Create
CompareOptions, setoptions.advanced_options.compare_list_definitionstoTrue, and pass the options toDocument.compare. Each list paragraph whose numbering or bullet changed receives aFORMAT_CHANGErevision.What kind of revision does a numbering change create? Each affected list paragraph gets a revision of type
RevisionType.FORMAT_CHANGE. Accepting it applies the edited file’s list formatting, and rejecting it keeps the original.Does the option work together with ignore_formatting? No. When
CompareOptions.ignore_formattingisTrue, numbering changes are not reported, even ifcompare_list_definitionsisTrue.What does Document.compare return? Nothing. It writes the differences as revisions into the document you call it on, so you read them from that document’s
revisionscollection.Which version of Aspose.Words for Python added this option? The
compare_list_definitionsproperty ofAdvancedCompareOptionswas added in Aspose.Words for Python via .NET 26.9.
