From version < 14.1 >
edited by Marius Dumitru Florea
on 2019/12/11 16:23
To version < 16.1 >
edited by Marius Dumitru Florea
on 2019/12/12 14:59
< >
Change comment: There is no comment for this version

Summary

Details

ExtensionCode.ExtensionClass[0]
Description
... ... @@ -135,25 +135,17 @@
135 135  To compute the changes you need to use the ##XMLDiff## component.
136 136  
137 137  {{code language="java"}}
138 -public interface XMLDiff
139 -{
140 - /**
141 - * Computes the difference between two XML nodes and their descendants. When a value node type (e.g. text,
142 - * attribute, comment) is modified we compute the difference on the text value using the splitter indicated by the
143 - * configuration. Otherwise the difference is expressed at node level, as if two lists of nodes are compared.
144 - * <p>
145 - * The result is a mapping between nodes from the left side and the patches that need to be applied to these nodes
146 - * in order for the left tree to become the right tree. If the root nodes of the left and right trees don't match
147 - * then this change is mapped to the {@code null} key.
148 - *
149 - * @param left the left side of the comparison
150 - * @param right the right side of the comparison
151 - * @param config the configuration
152 - * @return the differences between the two XML nodes
153 - * @throws DiffException if the difference can't be computed
154 - */
155 - Map<Node, Patch<?>> diff(Node left, Node right, XMLDiffConfiguration config) throws DiffException;
156 -}
138 [email protected]
139 +private XMLDiff xmlDiff;
140 +
141 [email protected]
142 +private XMLDiffConfiguration config;
143 +
144 +...
145 +
146 +Document left = parseXML("...");
147 +Document right = parseXML("...");
148 +Map<Node, Patch<?>> patches = this.xmlDiff.diff(left, right, this.config);
157 157  {{/code}}
158 158  
159 159  The default implementation uses the list diff API to compute the changes between child nodes, attributes and text content. The algorithm is quite simple:
... ... @@ -182,33 +182,68 @@
182 182  
183 183  The similarity threshold (0.6 by default) can be changed from the configuration.
184 184  
177 +As indicated in the algorithm described above, you can also change from the configuration the text splitter used for a specific node type. And, of course, you can implement your own splitter component.
178 +
179 +{{code language="java"}}
180 [email protected]
181 [email protected]("myCustomSplitter")
182 +private StringSplitter myCustomSplitter;
183 +
184 [email protected]ject
185 +private XMLDiffConfiguration config;
186 +
187 +...
188 +
189 +((DefaultXMLDiffConfiguration) this.config).setSplitterForNodeType(Node.TEXT_NODE, this.myCustomSplitter);
190 +{{/code}}
191 +
185 185  == Displaying the Changes ==
186 186  
187 -To compute and display the changes you can use the ##XMLDiffManager## component.
194 +The component responsible for computing and displaying the changes is ##XMLDiffManager##. There's no generic (default) implementation provided at the moment. The provided implementation is dedicated to displaying changes between HTML documents.
188 188  
189 189  {{code language="java"}}
190 -public interface XMLDiffManager
191 -{
192 - /**
193 - * Computes and marks the differences between two XML documents.
194 - *
195 - * @param left the left side of the comparison
196 - * @param right the right side of the comparison
197 - * @param config the configuration
198 - * @return the differences between the two XML documents
199 - * @throws DiffException if the difference can't be computed
200 - */
201 - String diff(String left, String right, XMLDiffConfiguration config) throws DiffException;
202 -}
197 +@Inject
198 +@Named("html/unified")
199 +private XMLDiffManager unifiedHTMLDiffManager;
200 +
201 +@Inject
202 [email protected]Named("html")
203 +private XMLDiffConfiguration config;
204 +
205 +...
206 +
207 +String previousHTML = "...";
208 +String nextHTML = "...";
209 +String diff = this.unifiedHTMLDiffManager.diff(previousHTML, nextHTML, this.config)
203 203  {{/code}}
204 204  
205 205  You can control from the configuration which ##XMLDiffFilter##s are applied on the XML documents before and after computing the changes. You can also implement your own filters, e.g. to remove irrelevant changes, or to ignore parts of the XML documents while computing the changes. The default configuration applies a filter to mark context (unmodified) nodes after the changes are computed.
206 206  
207 -=== HTML Visual Diff ===
214 +{{code language="java"}}
215 [email protected]
216 [email protected]("myCustomFilter")
217 +private XMLDiffFilter myCustomFilter;
208 208  
209 -The ##XMLDiffManager## has an implementation dedicated to computing a visual diff on HTML. Best is to use the provided script service:
219 [email protected]
220 [email protected]("html")
221 +private XMLDiffConfiguration config;
210 210  
223 +...
224 +
225 +this.config.getFilters().add(this.myCustomFilter);
226 +{{/code}}
227 +
228 +== Script Service ==
229 +
230 +Here's how you can compute and display the changes from a Velocity script:
231 +
211 211  {{code language="none"}}
233 +{{velocity}}
234 +{{html clean="false"}}
235 +#set ($discard = $xwiki.ssfx.use('uicomponents/viewers/diff.css', true))
236 +#set ($discard = $xwiki.jsfx.use('uicomponents/viewers/diff.js'))
237 +#set ($previousHTML = '<p>one two three</p>')
238 +#set ($nextHTML = '<p>one 2 three</p>')
212 212  <div class="html-diff">
213 213   #set ($htmlDiff = $services.diff.html.unified($previousHTML, $nextHTML))
214 214   #if ($htmlDiff == '')
... ... @@ -219,6 +219,8 @@
219 219   $htmlDiff
220 220   #end
221 221  </div>
249 +{{/html}}
250 +{{/velocity}}
222 222  {{/code}}
223 223  
224 224  You can configure the diff by passing a third argument:
... ... @@ -225,6 +225,10 @@
225 225  
226 226  {{code language="none"}}
227 227  #set ($config = $services.diff.html.defaultConfiguration)
257 +#set ($discard = $config.setSimilarityThreshold(0.6))
258 +#set ($discard = $config.addFilter('hintOfMyCustomFilter'))
259 +## Change the splitter used for text nodes from 'character' to 'word'.
260 +#set ($discard = $config.setSplitterForNodeType(3, 'word'))
228 228  #set ($htmlDiff = $services.diff.html.unified($previousHTML, $nextHTML, $config))
229 229  {{/code}}
230 230  

Get Connected