Page 1 of 1

findNodesByXPath within resolveReference unreliable

Posted: Tue May 05, 2015 8:30 am
by Patrik
Hi,

I implemented my own ValidatingAuthorReferenceResolver class (derived from DITAConRefResolver) and need to use findNodesByXPath inside resolveReference. In priciple this works fine but when the reference is resolved for the first time (after adding the element to be resolved or modifying in in text mode and switching to author mode) the result is wrong. A refresh always resolves it but with the increasing use of this feature also the annoyance grows.

Here is a minimized sample:

Code: Select all

public boolean hasReferences(AuthorNode node) {
if (node.getName().equals("resolveReferenceTest")) return true;
return super.hasReferences(node);
}

@Override
public String getDisplayName(AuthorNode node) {
if (node.getName().equals("resolveReferenceTest")) return "resolveReferenceTest";
return super.getDisplayName(node);
}

@Override
public String getReferenceSystemID(AuthorNode node, AuthorAccess authorAccess) {
if (node.getName().equals("resolveReferenceTest")) return node.getXMLBaseURL().toExternalForm();
return super.getReferenceSystemID(node, authorAccess);
}

@Override
public String getReferenceUniqueID(AuthorNode node) {
if (node.getName().equals("resolveReferenceTest")) return "resolveReferenceTest";
return super.getReferenceUniqueID(node);
}


@Override
public SAXSource resolveReference(AuthorNode node, String systemID, AuthorAccess authorAccess, EntityResolver entityResolver) throws ReferenceResolverException {
if (node.getName().equals("resolveReferenceTest")) {
try {
AuthorNode[] results = authorAccess.getDocumentController().findNodesByXPath("parent::*", node, true, true, false, false);
if (results.length == 1) {
final String resultString = "<p>Parent: " + results[0].getDisplayName() + "</p>";
logger.info("resultString: " + resultString);
return new SAXSource(
authorAccess.getXMLUtilAccess().newNonValidatingXMLReader(),
new InputSource(new StringReader(resultString)));
} else {
throw new ReferenceResolverException("No parent", true, true);
}
} catch (AuthorOperationException e) {
throw new ReferenceResolverException(e.getMessage(), true, true);
}
}
return super.resolveReference(node, systemID, authorAccess, entityResolver);
}

@Override
public void checkTarget(AuthorNode node, AuthorDocument targetDocument) throws ValidatingReferenceResolverException {
if (node.getName().equals("resolveReferenceTest")) return;
super.checkTarget(node, targetDocument);
}
Now when adding an element resolveReferenceTest within the body of a topic (as root element) the exception "No parent" is thrown. In other cases (with more content in the file) the name of another element is displayed!?

Is there anything I can do about it? Maybe automatically do a refresh on a suitable event? (I can't call DocumentController.refreshNodeReferences inside resolveReference since it results in a recursion).

Re: findNodesByXPath within resolveReference unreliable

Posted: Tue May 05, 2015 11:17 am
by alex_jitianu
Hello Patrik,

In this situation, the resolve references call comes before the node is fully connected in the document. Fortunately the node is linked to its parent so you can use node.getParent() instead.

Best regards,
Alex

Re: findNodesByXPath within resolveReference unreliable

Posted: Tue May 05, 2015 11:26 am
by Patrik
Hi Alex,

this was just a minimized sample to demonstrate the problem. In my actual use-case I need to execute more complex xpath expressions (specified as default attributes of the element).

Patrik

Re: findNodesByXPath within resolveReference unreliable

Posted: Tue Jan 05, 2016 11:14 am
by Radu
Hi Patrik,

Just to update this older forum thread, in Oxygen 17.1 you should be able to run an xpath using our API on the resolveReference callback.

Regards,
Radu