В 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
там или внутри RunIns
(с R
внутри этого). Для этого у меня есть половинное решение ниже. Самое интересное начинается в строке 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;
}