Page 1 of 1

Relative XPath

Posted: Tue Jul 05, 2011 11:53 pm
by xsaero00
If I have AuthorAccess A and AuthorElement E how do I find number of previous siblings of E?

Re: Relative XPath

Posted: Wed Jul 06, 2011 12:12 am
by xsaero00
And in general how do I do relative XPath given a particular AuthorElement?

Re: Relative XPath

Posted: Wed Jul 06, 2011 9:12 am
by Radu
Hi Mike,

So:
If I have AuthorAccess A and AuthorElement E how do I find number of previous siblings of E?
Like this:

Code: Select all

    //The current element
AuthorElement elem = ......
AuthorNode parent = elem.getParent();
List<AuthorNode> contentNodes = ((AuthorParentNode)parent).getContentNodes();
int indexInParent = contentNodes.indexOf(elem);
for (int i = indexInParent - 1; i >= 0; i--) {
AuthorNode previousSibling = contentNodes.get(i);
}
And in general how do I do relative XPath given a particular AuthorElement?
We have such methods in our implementation but nothing exposed in the API. If you can give us an use case maybe we can add such a method in the API. Of course you can implement it yourself, here is some simplified code from the method we've got (without taking namespaces into account):

Code: Select all


  /**
* Get the xpath expression for the element from the caret position.
*
* counts the sibling elements before current element having the same name. The indexes are 1 based.
* @param currentNode
* @return The XPath expression
*/
public static String getXpathExpresionSimplified(AuthorNode currentNode) {
String toReturn = "";
while (currentNode != null && AuthorNode.NODE_TYPE_DOCUMENT != currentNode.getType()) {
// Traverse the ancestors of the current node and build xpath expr.
String name = currentNode.getName();
//
// Find the index of current element in the parent
//
String indexInParent = "";
AuthorParentNode parent = (AuthorParentNode) currentNode.getParent();
if (parent != null && AuthorNode.NODE_TYPE_DOCUMENT != parent.getType()) {
List children = parent.getContentNodes();
int index = 0;
for (Iterator iter = children.iterator(); iter.hasNext();) {
AuthorNode child = (AuthorNode) iter.next();
if (name.equals(child.getName())) {
index ++;
if (child == currentNode) {
indexInParent = "[" + index + "]";
break;
}
}
}
}

//
// Adds the XPath section corresponding to the current token item.
//
switch (currentNode.getType()) {
case AuthorNode.NODE_TYPE_ELEMENT:
toReturn = "/" + name + indexInParent + toReturn;
break;
case AuthorNode.NODE_TYPE_COMMENT:
// The token is comment.
toReturn = "/" + "comment()" + indexInParent + toReturn;
break;
case AuthorNode.NODE_TYPE_PI:
// The token is PI.
toReturn = "/" + "processing-instruction()" + indexInParent + toReturn;
break;
}
currentNode = currentNode.getParent();
}
return toReturn;
}
Regards,
Radu

Re: Relative XPath

Posted: Wed Jul 06, 2011 6:29 pm
by xsaero00
The use cases of it are plentiful. For example you want to select all elements of a certain type, within a given element. Currently I would probably solve such problem by traversing it using the AuthorNode API with some helping of recursion. But it would be much easier if there was a method like

Code: Select all


AuthorNode[] findNodesByXPath(java.lang.String xpathExpression, AuthorNode staringPoint)
then it would be a simple call like

Code: Select all


findNodesByXPath("descendant::*", element)
I noticed XPath expressions that you can run from author view are "current node" aware, so I am a bit surprised such API is not exposed.

Re: Relative XPath

Posted: Thu Jul 07, 2011 8:46 am
by Radu
Hi Mike,

Looking at the implementation of the current "findNodesByXPath" API methods, it seems that relative XPaths are executed in the context of the element in which the caret is placed. So as a workaround you can also move the caret in the element (at node.getStartOffset() + 1) on which you want to run the XPath and after the execution move it back to the original location.

But we'll probably also add methods to directly give the context node to the "findNodesByXPath" and also update the Javadoc to state how relative XPath expressions are handled.

Regards,
Radu

Re: Relative XPath

Posted: Thu Jul 07, 2011 5:56 pm
by xsaero00
Awesome. I did not know that. I always assumed the XPath methods are absolute. That will definitely work. Thanks.