Philippe Nobili wrote:
>
> The ValidateHook mechanism is really easy to develop & deploy. Ours is
> rather simple, just fixing bad IDs, excerpt:
>
> *if( element.hasAttribute(ID) ) {
>
> String idstring = element.getAttribute(ID) ;
>
> if( idstring == null || !XMLText.isNCName(idstring) ) {
>
> element.putAttribute(ID,generateID());
> }
> }
This is just the obvious part, but there is another part which
integrates the above snippet to XXE.
>
> *This works fine, except under one circumstance: newly created elements
> are not fixed and keep their bad ID.
>
> If we run the validator a second time (e.g. from XMLMind),
Such validators are automatically invoked when you use Tools|Validate or
File|Open and/or File|Save.
> their ID is fixed.
> If we create several new elements, then the ValidateHook fails to fix
> them all the first time it is ran, and fixes them all (as expected) the
> second time it is ran.
I don't see how this could be possible. Once attached to the document
tree, there is no difference between newly created elements and other
elements.
>
> Are newly created elements supposed to be traversed by the ValidateHook
> mechanism,
Yes.
> or did we do something wrong ?
Almost certainly yes.
Please find attached to your document the source code of a validator
which possibly modifies the document being validated/saved.
Tell your developers to adapt this code to your needs but to really
understand and keep the overall framework (Traversal.traverse,
element.isEditable(), doc.beginEdit()/doc.endEdit(),
UndoManager.describeUndo, etc).
All details are very important in order to have something which runs
really smoothly.
/*
* Ensures that the value of the cols attribute of the DocBook tgroup element
* corresponds to the actual number of columns of this tgroup.
*/
package com.xmlmind.xmleditext.docbook.table;
import java.net.URL;
import com.xmlmind.xml.doc.Element;
import com.xmlmind.xml.doc.Document;
import com.xmlmind.xml.doc.Traversal;
import com.xmlmind.xmledit.edit.UndoManager;
import com.xmlmind.xmleditapp.validatehook.Reason;
import com.xmlmind.xmleditapp.validatehook.ValidateHookBase;
import static com.xmlmind.xmleditext.docbook.table.TableAttributeName.COLS;
public final class ValidateHookImpl extends ValidateHookBase {
@Override
public void checkingDocument(final Document doc,
Reason reason, URL saveAsURL) {
// Do nothing unless we are saving the document.
if (reason == null) {
return;
}
switch (reason) {
case SAVE:
case SAVE_AS:
break;
default:
return;
}
final int[] fixes = new int[1];
Traversal.traverse(doc.getRootElement(), new Traversal.HandlerBase() {
public Object enterElement(Element element) {
String name = element.getLocalName();
if ("tgroup".equals(name) || "entrytbl".equals(name)) {
int columnCount = RowGroupInfo.getColumnCount(element);
if (columnCount > 0) {
int cols = element.getIntAttribute(COLS, -1);
if (cols != columnCount && element.isEditable()) {
if (fixes[0] == 0) {
doc.beginEdit();
}
element.putAttribute(COLS,
Integer.toString(columnCount));
++fixes[0];
}
}
}
return null;
}
});
if (fixes[0] > 0) {
doc.endEdit();
UndoManager.describeUndo(doc, Msg.msg("fixCols"));
}
}
}
--
XMLmind XML Editor Support List
[email protected]
http://www.xmlmind.com/mailman/listinfo/xmleditor-support