Relative XPath

Oxygen general issues.
xsaero00
Posts: 58
Joined: Sat Aug 01, 2009 12:57 am

Relative XPath

Post by xsaero00 »

If I have AuthorAccess A and AuthorElement E how do I find number of previous siblings of E?
xsaero00
Posts: 58
Joined: Sat Aug 01, 2009 12:57 am

Re: Relative XPath

Post by xsaero00 »

And in general how do I do relative XPath given a particular AuthorElement?
Radu
Posts: 9049
Joined: Fri Jul 09, 2004 5:18 pm

Re: Relative XPath

Post 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
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
xsaero00
Posts: 58
Joined: Sat Aug 01, 2009 12:57 am

Re: Relative XPath

Post 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.
Radu
Posts: 9049
Joined: Fri Jul 09, 2004 5:18 pm

Re: Relative XPath

Post 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
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
xsaero00
Posts: 58
Joined: Sat Aug 01, 2009 12:57 am

Re: Relative XPath

Post by xsaero00 »

Awesome. I did not know that. I always assumed the XPath methods are absolute. That will definitely work. Thanks.
Post Reply