Xpath expression won't select anything
HI there, I have an xml that is dynamically generated, from which I want to extract the information..I was using Xpath expressions but found out my xpath expression is not working properly it doesn't select anything.....here's my Java function which executes the xpath expression:
public void TraverseClass(NavigationTree parent,String name)
{
xPath = XPathFactory.newInstance().newXPath();
XPathExpression expr;
try {
expr = xPath.compile("Class[@name=\""+name+"\"]/Class");
Object result = expr.evaluate(document, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
JOptionPane.showMessageDialog(null,nodes.getLength());
for(int i=0;i<=nodes.getLength()-1;i++)
{
Node first=nodes.item(i);
Element node=(Element)first;
JOptionPane.showMessageDialog(null,"Found Classes inside "+name+" " +node.getAttribute("name"));
parent.foundClass(node.getAttribute("name"));
//Interfaces[i]=node.getAttribute("name");
开发者_StackOverflow }
expr = xPath.compile("Class[@name=\""+name+"\"]/Interfaces");
result = expr.evaluate(document, XPathConstants.NODESET);
nodes = (NodeList) result;
JOptionPane.showMessageDialog(null,nodes.getLength());
for(int i=0;i<=nodes.getLength()-1;i++)
{
Node first=nodes.item(i);
Element node=(Element)first;
JOptionPane.showMessageDialog(null,"Found Interfaces inside "+name+" "+node.getAttribute("name"));
parent.foundInterface(node.getAttribute("name"));
//Interfaces[i]=node.getAttribute("name");
}
expr = xPath.compile("Class[@name=\""+name+"\"]/Method");
result = expr.evaluate(document, XPathConstants.NODESET);
nodes = (NodeList) result;
JOptionPane.showMessageDialog(null,nodes.getLength());
for(int i=0;i<=nodes.getLength()-1;i++)
{
Node first=nodes.item(i);
Element node=(Element)first;
JOptionPane.showMessageDialog(null,"Found Methods inside "+name+" "+node.getAttribute("name"));
parent.foundMethod(node.getAttribute("name"));
//Interfaces[i]=node.getAttribute("name");
}
} catch (XPathExpressionException e) {
JOptionPane.showMessageDialog(null,"error: "+e.toString());
e.printStackTrace();
}
JOptionPane.showMessageDialog(null,"going one step back in Class "+name);
parent.goOneStepBack();
}
Now the xml file I am trying to parse is
<?xml version="1.0"?>
<program>
<Interface modifier="public" name="interface1">
<ParentInterface> i1</ParentInterface>
<ParentInterface> i2</ParentInterface>
<ParentInterface> i3</ParentInterface>
<Field modifier="" type="int" name="a,b,c">
</Field>
<Interface modifier="public" name="one">
<ParentInterface> two</ParentInterface>
</Interface>
<Class modifier="public" name="three">
<Parent>four</Parent>
</Class>
<Method modifier="" type="void" name="foo1">
<FormalParameter >
</FormalParameter>
</Method>
</Interface>
<Class modifier="" name="FrontPAge">
<Parent>JFrame</Parent>
<Field modifier="public" type="int" name="a,b,c">
</Field>
<Field modifier="" type="int" name="arr[]">
</Field>
<Field modifier="" type="int" name="arr2[]">
</Field>
<Field modifier="" type="int" name="num[]">
</Field>
<Field modifier="" type="FrontPAge" name="fp">
</Field>
<Constructor modifier="public" name="FRontPage">
<FormalParameter >
</FormalParameter>
<Statement> <![CDATA[System.out.println("It is a constructor")]]></Statement>
</Constructor>
<Method modifier="publicstatic" type="void" name="main">
<FormalParameter modifier="" type="String[]" var_name="args" >
</FormalParameter>
<Field modifier="" type="int" name="x,y,z">
</Field>
<Field modifier="" type="int" name="sum[]">
</Field>
<For>
<Itr_Var type="int">x</Itr_Var>
<Collection><![CDATA[num]]></Collection>
<Statement> <![CDATA[sum+=x]]></Statement>
</For>
<Interface modifier="public" name="qqq">
<ParentInterface> www</ParentInterface>
</Interface>
<Statement> <![CDATA[System.out.println("Runnable is gonna start")]]></Statement>
<Class name="Runnable">
<Method modifier="public" type="void" name="run">
<FormalParameter >
</FormalParameter>
<Statement> <![CDATA[System.out.println("Hello")]]></Statement>
</Method>
</Class>
<Statement> <![CDATA[EventQueue.invokeLater(newRunnable(){publicvoidrun() {System.out.println("Hello");}})]]></Statement>
<Statement> <![CDATA[System.out.println("Runnable Ends Here")]]></Statement>
<Statement> <![CDATA[c=b+d]]></Statement>
<Statement> <![CDATA[a=b+c]]></Statement>
</Method>
<Class modifier="" name="nested">
</Class>
<Interface modifier="public" name="xxx">
<ParentInterface> yyy</ParentInterface>
</Interface>
</Class>
</program>
Information: The name parameter of java function contains the name of one highest level classes,i.e descendants of root element which may futrther contain other classes/interfaces/methods...
Question: My problem is the expression I am using Class[@name=<ClassName>]/Class
should select all the classes from the xml,exclude everything other than select the class with the name and then select all the child classes of that class...same thing goes with the interfaces and methods...but it doesn't work at all!!!!....none of the expressions match anything....
I can't rely on absolute paths much because xml is generated dynamically from source codes and thus content of xml except for the root element too are subjected to change
This expression selects all nested classes (there is only one in your sample document: class "FrontPAge" has a nested class:
//Class/Class
or with name attribute
//Class[@name="FrontPAge"]/Class
Your expression should work, if you evaluate the root node but not the document (in Line 8). If you want to evaluate on the document, the first element is <program>
and you'd have to say
program/Class[@name=\"" + name + "\"]/Class
Off the records: I used this online xpath evaluator to verify the expressions. Just copy the sample document to the text field and play with XPath expressions
I think you may need to start your xpath expressions with program
as it is the root element
e.g:
expr = xPath.compile("program/Class[@name=\""+name+"\"]/Interfaces")
I haven't tested this out myself, but it's worth a try :)
精彩评论