Как принять исправления/отследить изменения (ins/del) в docx?

В MS-Word 2010 есть опция в разделе «Файл» -> «Информация», позволяющая проверить документ на наличие проблем, прежде чем делиться им. Это позволяет отслеживать изменения (до последней версии) и сразу удалять все комментарии и аннотации из документа.

введите здесь описание изображения

Доступна ли эта возможность и в docx4j, или мне нужно изучить соответствующие JAXB-объекты и написать обходной искатель? Выполнение этого вручную может потребовать много работы, так как мне придется добавить RunIns (w:ins) к R (w:r) и удалить RunDel (w:del). Я также однажды видел w:del внутри w:ins. В этом случае я не знаю, появляется ли это также наоборот или в более глубоких вложениях.

Дальнейшие исследования выявили этот XSLT: https://github.com/plutext/docx4all/blob/master/docx4all/src/main/java/org/docx4all/util/ApplyRemoteChanges.xslt Мне не удалось запустить это в docx4j, но вручную разархивировав docx и извлекая document.xml. После применения xslt к простому document.xml я снова завернул его в контейнер docx, чтобы открыть его с помощью MS-Word. Результат был не таким, как если бы он принял исправление с самим MS-Word. Более конкретно: XSLT удалил удаленный помеченный текст (в таблице), но не точку в списке перед текстом. Это довольно часто встречается в моем документе.

Если этот запрос невозможно решить простым способом, я изменю ограничения. Мне достаточно иметь метод для получения всего текста ContentAccessor, как String. ContentAccessor может быть P или Tc. Строка должна быть внутри R там или внутри RunInsR внутри этого). Для этого у меня есть половинное решение ниже. Самое интересное начинается в строке else if (child instanceof RunIns) {. Но, как упоминалось выше, я не уверен, как могут появиться вложенные операторы del/ins и хорошо ли это справится с ними. И результаты все равно не такие, как если бы я раньше готовил документ в MS-Word.

//Similar to:
//http://www.docx4java.org/forums/docx-java-f6/how-to-get-all-text-element-of-a-paragraph-with-docx4j-t2028.html
private String getAllTextfromParagraph(ContentAccessor ca) {
    String result = "";
    List<Object> children = ca.getContent();
    for (Object child : children) {
        child = XmlUtils.unwrap(child);
        if (child instanceof Text) {
            Text text = (Text) child;
            result += text.getValue();
        } else if (child instanceof R) {
            R run = (R) child;
            result += getTextFromRun(run);
        }
        else if (child instanceof RunIns) {
            RunIns ins = (RunIns) child;
            for (Object obj : ins.getCustomXmlOrSmartTagOrSdt()) {
                if (obj instanceof R) {
                    result += getTextFromRun((R) obj);
                }
            }
        }
    }
    return result.trim();
}

private String getTextFromRun(R run) {
    String result = "";
    for (Object o : run.getContent()) {
        o = XmlUtils.unwrap(o);
        if (o instanceof R.Tab) {
            Text text = new Text();
            text.setValue("\t");
            result += text.getValue();
        }
        if (o instanceof R.SoftHyphen) {
            Text text = new Text();
            text.setValue("\u00AD");
            result += text.getValue();
        }
        if (o instanceof Br) {
            Text text = new Text();
            text.setValue(" ");
            result += text.getValue();
        }
        if (o instanceof Text) {
            result += ((Text) o).getValue();
        }
    }
    return result;
}

person froehli    schedule 07.08.2017    source источник
comment
Для извлечения текста см. github. .com/plutext/docx4j/blob/master/src/main/java/org/docx4j/   -  person JasonPlutext    schedule 08.08.2017
comment
Я был бы склонен попробовать использовать XSLT для принятия изменений, а не обход JAXB. Я думал, что где-то есть код для этого, но я не могу найти его прямо сейчас...   -  person JasonPlutext    schedule 08.08.2017
comment
Для XSLT существует github.com/plutext/docx4j/blob/master/src/main/java/org/docx4j/ Обратите внимание, что это преобразует представление Flat OPC, поэтому оно также имеет доступ к другим частям (например, к части Styles) . Было бы просто написать что-то, что просто преобразует основную часть документа.   -  person JasonPlutext    schedule 09.08.2017
comment
См. msdn.microsoft.com/en-us/ библиотека/ee836138(v=office.12).aspx   -  person JasonPlutext    schedule 09.08.2017
comment
Вы эту ссылку имели в виду? github.com/ plutext/docx4all/blob/master/docx4all/src/main/java/ Я не мог заставить его работать. Я не знаком с написанием сложных XSLT. Насколько я понимаю вашу ссылку msdn, плоское представление OPC не проблема. Моя программа читает файл .docx, указывает конкретные заголовки и соответствующие таблицы. Данные из таблиц извлекаются построчно (и столбец за столбцом) и сохраняются в моей собственной структуре данных. После этого возврата в docx нет.   -  person froehli    schedule 09.08.2017
comment
Но входной документ имеет различное количество отслеживаемых изменений. Моя процедура заключалась в том, чтобы принять эти изменения с помощью MS-Word перед загрузкой документа с помощью docx4j. Но я надеялся на более удобный способ. Я попытался позаботиться о RunIns с помощью простого оператора If, но, похоже, он не работает должным образом. Каков наилучший способ добиться этого? Для вашей ссылки github.com/plutext/docx4j/blob/master/src/main/java/org/docx4j/ Мне не хватает описания параметров преобразования.   -  person froehli    schedule 09.08.2017


Ответы (1)


https://github.com/plutext/docx4j/commit/309a8e4008553452ebe675e81def30aab97542a2?w=1 добавлен метод для преобразования только одной части и пример кода для его использования для принятия изменений.

XSLT — это именно то, что вы нашли (перелицензировано как Apache 2):

    <?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
  xmlns:o="urn:schemas-microsoft-com:office:office"
  xmlns:v="urn:schemas-microsoft-com:vml"
  xmlns:WX="http://schemas.microsoft.com/office/word/2003/auxHint"
  xmlns:aml="http://schemas.microsoft.com/aml/2001/core"
  xmlns:w10="urn:schemas-microsoft-com:office:word"
  xmlns:pkg="http://schemas.microsoft.com/office/2006/xmlPackage"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:ext="http://www.xmllab.net/wordml2html/ext"
  xmlns:java="http://xml.apache.org/xalan/java"
  xmlns:xml="http://www.w3.org/XML/1998/namespace"
  version="1.0"
        exclude-result-prefixes="java msxsl ext o v WX aml w10">


  <xsl:output method="xml" encoding="utf-8" omit-xml-declaration="no" indent="yes" />


  <xsl:template match="/ | @*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="w:del" />

  <xsl:template match="w:ins" >
    <xsl:apply-templates select="*"/>
  </xsl:template>

</xsl:stylesheet>

Вам потребуется добавить поддержку других элементов, указанных в ссылке MSDN. Если вы это сделаете, я буду рад получить запрос на включение

person JasonPlutext    schedule 09.08.2017
comment
спасибо пока! Не могли бы вы предоставить мне JAR-файл, содержащий эти изменения? Я использую maven для получения новейшей версии docx4j. Мне кажется довольно сложным вставить новый код в мой проект. Я посмотрю, смогу ли я улучшить этот XSLT. - person froehli; 11.08.2017
comment
вы можете установить в свой репозиторий maven, загрузив исходный код, затем запустив mvn install, затем mvn install:install-file (вам понадобятся различные аргументы) - person JasonPlutext; 14.08.2017
comment
Мне не удалось установить два файла в одиночку, но сейчас я создаю .jar с помощью mave. (См.: stackoverflow.com/questions/45754589/). Я попробовал существующий xslt с новым документом Word, и на простом примере это сработало. Но мой продуктивный docx выдает ошибку: WARN org.docx4j.jaxb.JaxbValidationEventHandler .handleEvent line 88 - [ERROR] : unerwartetes Element (URI:"http://schemas.openxmlformats.org/markup-compatibility/2006", lokal:"AlternateContent"). Erwa. Я добавил xmlns:mc в xslt, но ничего не изменилось. - person froehli; 18.08.2017
comment
Если вы разместите еще один вопрос со ссылкой на метод преобразования и скопируете свой комментарий, объясняющий, что произошло, я отвечу там. - person JasonPlutext; 20.08.2017
comment
См. сейчас github.com/plutext/docx4j/commit/ Вы можете либо загрузите docx4java.org/docx4j/docx4j-nightly-20170821.jar затем используйте mvn install:install-file или вы можете извлечь изменения и запустить mvn install - person JasonPlutext; 21.08.2017
comment
На сегодняшний день я перестал копаться в этом. Использование PowerTools в C# кажется гораздо более удобным. Но перед этим я столкнулся с проблемой, которой хочу поделиться. Похоже, что указанная документация «Принятие изменений в документах по обработке текстов Open XML» устарела. Дают алгоритмы принятия изменений в структуре таблиц. В моем тесте Word 2010 и новее не зафиксировали никаких изменений в структуре таблиц, таких как объединение ячеек или их удаление. Word даже выводит предупреждение об этом. - person froehli; 08.09.2017