Accepting All Changes With XSLT

When publishing documents that contain track changes information, it's a good idea to make sure that all the changes have been accepted, before you push the document out to the world. We've previously shown how you can detect that change information is present, but we can go one step further and remove that information and publish the document as if all the changes had been accepted.

In this case, we'll use XSLT to remove the track changes markup, but it's also possible to use plain string parsing - we'll show that in a future article.

The first step is to set up a simple identity transform style sheet, so that by default all the content is copied over unchanged:

<?xml version="1.0" ?>
<xs:stylesheet xmlns:xs="http://www.w3.org/1999/XSL/Transform"
  version="1.0" xmlns:html="http://www.w3.org/1999/xhtml">
    <xs:template match="@*|node()">
      <xs:copy>
        <xs:apply-templates select="@*|node()" />
      </xs:copy>
    </xs:template>
</xsl:stylesheet>

Next, lets strip out the <change> elements that mark where changes occurred in the document. This is just a simple template that matches the change element and outputs nothing:

<xs:template match="html:change" />

Next, we'll use the same technique, to strip out the <div> element that contains the actual track changes information. The match attribute is slightly more complex here because we only want to match the <div> element that has a  <trackchanges> element as a child:

<xs:template match="html:div[./html:trackchanges]" />

We could of course just remove the track changes element, but that would leave an empty <div> tag around unnecessarily.

The complete style sheet is then:

<?xml version="1.0" ?>
<xs:stylesheet xmlns:xs="http://www.w3.org/1999/XSL/Transform"
       version="1.0" xmlns:html="http://www.w3.org/1999/xhtml">

    <xs:template match="html:change" />

    <xs:template match="html:div[./html:trackchanges]" />

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

One catch: you need to make sure that your document is being output as XML or XHTML instead of plain HTML. Use the outputXML and outputXHTML attributes of the htmlFilter element in your configuration file to control this.

Adrian spends his days working out ways to make life easier for Ephox clients through initiatives like LiveWorks! Previously a senior engineer, he has now moved on to the fancier sounding title of CTO.

Leave a Reply