Коли ви порівнюєте два файли Word і єдина різниця полягає в тому, як нумерується список, наприклад, пункти, які були 1. і 2. тепер стали a. і b., або нумерований список перетворився на маркований, Aspose.Words за замовчуванням не повідомляє про відмінності. У цьому підручнику показано, як виявляти зміни нумерації під час порівняння файлів Word у Python. Також він пояснює, як переглядати, приймати або відхиляти знайдені зміни.

Ключові висновки

  • За замовчуванням зміна стилю нумерації списку або символу маркера не створює жодних змін при порівнянні файлів Word.
  • Встановлення options.advanced_options.compare_list_definitions = True повідомляє про кожен змінений абзац списку як ревізію FORMAT_CHANGE.
  • Зміни тексту всередині пунктів списку повідомляються в будь‑якому випадку. Опція лише додає зміни нумерації та маркерів поверх.
  • ignore_formatting=True приховує зміни нумерації, навіть коли опція увімкнена.

Чому зміни нумерації не відображаються за замовчуванням

Нумерація та маркери у Word беруться з визначення списку. Воно описує, як виглядає кожен рівень списку: стиль номеру (1., a., i.), символ маркера та пов’язане форматування. Коли ви порівнюєте документи, Aspose.Words за замовчуванням слідує Microsoft Word і виключає визначення списків з порівняння. Тому, якщо змінилася лише нумерація, порівняння не виявляє нічого для звіту.

Параметр compare_list_definitions не має еквіваленту у Word. Він повідомляє Aspose.Words включати визначення списків у порівняння. Ось що ми побачили під час порівняння списків з двома елементами у версії 26.9:

Оригінальний списокВідредагований списокОпція вимкненоОпція увімкнено
Нумерований 1. 2.Маркірований0 ревізій2 FORMAT_CHANGE
Нумерований 1. 2.Літерований a. b.0 ревізій2 FORMAT_CHANGE
Нумерований, “Елемент 2”Маркірований, “Елемент два”2 (DELETION, INSERTION)4 (додає 2 FORMAT_CHANGE)
НумерованийІдентичний нумерований список0 ревізій0 ревізій

Останній рядок має значення на практиці. Увімкнення цієї опції не створює додаткових ревізій для списків, які однакові в обох файлах.

Вимоги

Вам потрібен Aspose.Words for Python via .NET 26.9 або новіша версія. Встановіть або оновіть його з PyPI:

pip install --upgrade "aspose-words>=26.9"

Без ліцензії Aspose.Words працює в режимі оцінки з обмеженнями. Тимчасова ліцензія тимчасова ліцензія знімає їх під час тестування.

Побачте різницю: зміни нумерації з параметром і без нього

Наступний скрипт створює два документи, які містять однакові два елементи. Перший використовує нумерований список, а другий — маркований список. Він порівнює їх двічі: один раз з вимкненим параметром і ще раз з увімкненим, щоб ви могли точно побачити, які зміни вносить параметр.

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")

Запуск скрипту виводить:

compare_list_definitions=False: 0 revision(s)
compare_list_definitions=True: 2 revision(s)
  FORMAT_CHANGE: Item 1
  FORMAT_CHANGE: Item 2

Як працює код

  • build_list_document використовує DocumentBuilder.list_format для запуску стандартного нумерованого або маркованого списку, записує два елементи, а потім викликає remove_numbers(), щоб подальші абзаци не були частиною списку.
  • CompareOptions.advanced_options надає доступ до compare_list_definitions, який за замовчуванням має значення False.
  • original.compare(...) порівнює original з edited і фіксує різниці як ревізії всередині original. Метод повертає None, тому результати слід читати з документа, на якому ви викликали його.
  • parent_node кожної ревізії — це абзац списку, форматування якого змінилося. revision_type має значення RevisionType.FORMAT_CHANGE для змін нумерації та маркерів.

Виявлення змін нумерації між двома файлами Word

У реальному робочому процесі ви порівнюєте два існуючі файли, наприклад дві версії контракту. Такі порівняння зазвичай містять інші правки, тому скрипт нижче залишає лише зміни форматування, які розташовані у абзацах списку.

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")

У нашому тесті версія 2 контракту змінила нумерований список на маркери та також зробила незв’язане речення жирним. Результат був:

Total revisions: 5
Formatting changes on list paragraphs: 2
  Invoices are due in 30 days.
  Late fees apply after 45 days.

Фільтр вибирає два елементи списку та пропускає зміну жирного шрифту, оскільки ця ревізія стосується тексту, а не абзацу списку. Майте на увазі, що він відповідає будь‑якій зміні форматування на рівні абзацу в елементі списку, наприклад зміненому відступу, а не лише нумерації. Перевірте збережений документ, якщо потрібно розрізнити їх.

Переглянути, прийняти або відхилити зміни нумерації

Оскільки зміни нумерації є звичайними змінами формату, ви обробляєте їх так само, як будь‑яке інше виправлення:

  • revisions.accept_all() застосовує відредаговане форматування списку. У першому прикладі обидва елементи стають маркерами.
  • revisions.reject_all() зберігає оригінальне форматування, тому елементи залишаються нумерованими 1. і 2..
  • Збереження документа записує ревізії як відстежувані зміни, тому рецензенти можуть відкрити файл у Microsoft Word і самостійно вирішити, які зміни прийняти.

Ви також можете викликати accept() або reject() для окремих об’єктів Revision, наприклад, лише для елементів у списку list_changes, згаданому в попередньому розділі.

Коли виявляти зміни нумерації

Увімкніть цю опцію, коли нумерація списку має значення для ваших рецензентів. Юридичні та політичні документи — поширений випадок: перенумерація пунктів з 1. на (a) змінює спосіб, яким інші документи посилаються на них, тому рецензент повинен це бачити. Це також корисно, коли ви переносите документи між системами і хочете переконатися, що нумерація списку залишилася незмінною після переміщення.

Вимкніть його, коли вас цікавить лише формулювання. Огляди вмісту, перевірки перекладу та дифі на рівні тексту легше читати без змішаних правок форматування.

Що слід враховувати

  • ignore_formatting перевизначає параметр. Якщо ви встановите options.ignore_formatting = True, зміни нумерації не будуть повідомлені, навіть при compare_list_definitions = True.
  • Файли не повинні містити ревізії перед порівнянням. Якщо будь-який документ вже має відстежені зміни, compare викликає RuntimeError, повідомляючи, що порівнювані документи не повинні мати ревізій. Спочатку прийміть або відхиліть існуючі ревізії. Це також означає, що ви не можете виконати друге порівняння документа, який вже містить результати першого; кожного разу перезавантажуйте файли.
  • Інші ревізії все ще відображаються. Вставлений або видалений текст у пункті списку повідомляється незалежно від того, чи ввімкнено параметр, тому перевірте revision_type, якщо потрібно розділити зміни нумерації від змін формулювання.

Наступні кроки

Стаття Порівняти документи в документації Aspose.Words for Python охоплює інші налаштування порівняння, включаючи деталізацію, ціль порівняння та параметри ігнорування.

Питання та відповіді

  1. Чому Aspose.Words не виявляє зміни нумерації під час порівняння файлів Word? За замовчуванням Aspose.Words слідує Microsoft Word і не включає визначення списків, такі як стиль нумерації чи символ маркера, у порівняння. Список, який змінюється з номерів на маркери, не створює жодних змін, якщо не ввімкнути compare_list_definitions.

  2. Як виявити зміни нумерації в Python? Створіть CompareOptions, встановіть options.advanced_options.compare_list_definitions у True і передайте параметри у Document.compare. Кожен абзац списку, у якого нумерація або маркер змінився, отримує ревізію FORMAT_CHANGE.

  3. Який тип ревізії створює зміна нумерації? Кожен змінений абзац списку отримує ревізію типу RevisionType.FORMAT_CHANGE. Прийняття її застосовує форматування списку відредагованого файлу, а відхилення зберігає оригінал.

  4. Чи працює ця опція разом з ignore_formatting? Ні. Коли CompareOptions.ignore_formatting є True, зміни нумерації не повідомляються, навіть якщо compare_list_definitions є True.

  5. Що повертає Document.compare? Нічого. Він записує відмінності як ревізії у документ, на якому ви його викликаєте, тому ви читаєте їх з колекції revisions цього документа.

  6. Яка версія Aspose.Words for Python додала цю опцію? Властивість compare_list_definitions класу AdvancedCompareOptions була додана в Aspose.Words for Python via .NET 26.9.

Отримайте безкоштовну ліцензію та підтримку