【问题标题】:How to accept revisions / track changes (ins/del) in a docx?如何在 docx 中接受修订/跟踪更改(ins/del)?
【发布时间】:2018-01-14 15:29:35
【问题描述】:

在 MS-Word 2010 中,文件 -> 信息下有一个选项,用于在共享文档之前检查文档是否存在问题。这使得处理跟踪更改(到新的最新版本)和一次从文档中删除所有 cmets 和注释成为可能。

这种可能性在 docx4j 中是否也可用,还是我需要研究相应的 JAXB 对象并编写遍历查找器? 手动执行此操作可能需要大量工作,因为我必须将 RunIns (w:ins) 添加到 R (w:r) 并删除 RunDel (w:del)。我还曾在w:ins 中看到过w:del。在这种情况下,我不知道反之亦然还是出现在更深的嵌套中。

进一步的研究提出了这个 XSLT: https://github.com/plutext/docx4all/blob/master/docx4all/src/main/java/org/docx4all/util/ApplyRemoteChanges.xslt 我无法在 docx4j 中运行它,而是手动解压缩 docx 并提取 document.xml。在普通 document.xml 上应用 xslt 后,我​​再次将其包装在 docx 容器中以使用 MS-Word 打开它。结果与接受 MS-Word 本身的修订不同。更具体:XSLT 删除了已删除的标记文本(在表格中),但没有删除文本前的列表点。这在我的文档中经常出现。

如果此请求无法以简单的方式解决,我将更改约束。对于我来说,有一个方法来获取 ContentAccessor 的所有文本就足够了,就像 String。 ContentAccessor 可以是PTc。字符串应在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;
}

【问题讨论】:

标签: java xslt ms-word docx4j wordml


【解决方案1】:

https://github.com/plutext/docx4j/commit/309a8e4008553452ebe675e81def30aab97542a2?w=1 添加了一种仅转换一个 Part 的方法,以及用于接受更改的示例代码。

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 链接中标识的其他元素的支持。如果你这样做,我很乐意收到拉取请求

【讨论】:

  • 谢谢!您能给我提供一个包含这些更改的 JAR 文件吗?我使用 maven 来获取最新的 docx4j 版本。对我来说,将新代码放入我的项目中似乎相当复杂。我会看看我是否能够改进这个 XSLT。
  • 您可以通过下载源代码,然后运行 ​​mvn install,然后运行 ​​mvn install:install-file(您需要各种 args)来安装到您的 maven 存储库
  • 我无法单独安装这两个文件,但我现在自己用 mave 构建了一个 .jar。 (见:stackoverflow.com/questions/45754589/…)。我用一个新的 word 文档尝试了现有的 xslt,它在一个简单的示例中工作。但我富有成效的 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 但没有任何改变。
  • 如果您发布另一个引用转换方法的问题并复制您的评论来解释发生了什么,我会在那里回答。
  • 立即查看 github.com/plutext/docx4j/commit/… 您可以下载 docx4java.org/docx4j/docx4j-nightly-20170821.jar 然后使用 mvn install:install-file 或者您可以拉取更改并运行 mvn install
猜你喜欢
  • 1970-01-01
  • 2013-01-18
  • 1970-01-01
  • 2011-01-16
  • 1970-01-01
  • 2018-08-16
  • 2012-02-20
  • 1970-01-01
  • 2019-08-16
相关资源
最近更新 更多