I've written what I want to achieve. however, getElementIdx()
function doesn't return proper count. There's an issue with getPreviousSibling()
but I don't know why.
public static String getElementXpath(DOMElement elt){
String path = "";
try{
for (; elt != null; elt = (DOMElement) elt.getParentNode()){
int idx = getElementIdx(elt);
String xname = elt.getTagName().toString();
if (idx >= 1) xname += "[" + idx + "]";
path = "/" + xname + path;
}
}catch(Exception ee){
}
return path;
}
public static int getElementIdx(DOMElement elt) {
int count = 1;
try{
for (DOMElement sib = (DOMElement) elt.getNextSibling(); sib != null; sib = (DOMElement) sib.getNextSibling())
{
if(sib.getTagName().equals(elt.getTagName())){
count++;
}
}
}catch(Exception ee){
}
return count;
}
Your title talks about getPreviousSibling()
, but your code only uses getNextSibling()
- why? I can't see why you'd want to use getNextSibling()
at all... you want to find out how many elements of the same name come before the current one, not how many come after it.
The fact that you're catching and swallowing exceptions is also deeply suspicious... why would you want to do that? If you have an exception, shouldn't the method terminate with an exception?
You should also probably take account of the fact that getPreviousSibling
may not return an element - it may return a text node, for example. You'll want to skip over those - currently you'd get an exception, which would terminate the loop and return the current count.
If these don't help, please post some sample XML, point out a node, and say what the code is currently returning (as well as posting your updated code). Just saying it doesn't return the proper count isn't nearly as useful as saying what it does return, and what you expected it to return.
EDIT: This is what I'd expect the code to look like:
public static int getElementIndex(Element original) {
int count = 1;
for (Node node = original.getPreviousSibling(); node != null;
node = node.getPreviousSibling()) {
if (node instanceof Element) {
Element element = (Element) node;
if (element.getTagName().equals(original.getTagName()) {
count++;
}
}
}
return count;
}
You could also use if (node.getNodeType() == Node.ELEMENT_NODE)
instead of the instanceof
test.
Dom4j xpath support is really good, you can access any element by providing the xpath expression.
However I'm not sure whether the reverse is true, i.e. whether given an element you can derive the xpath expression.
See the api at http://www.docjar.com/projects/dom4j-1.6.1-code.html
Note avoid www.dom4j.org, it appears to have been hi-jacked by some kind of spammy link farm.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With