你好, 我有一个动态生成的xml,我想从中提取信息。我正在使用Xpath表达式,但发现我的xpath表达式工作不正常它没有选择任何东西.....这里是我的Java函数执行xpath表达式:
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");
}
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();
}
现在我想解析的xml文件是
<?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>
信息:java函数的name参数包含一个最高级别类的名称,即根元素的后代,可能还包含其他类/接口/方法......
问题:我的问题是我使用的表达式Class[@name=<ClassName>]/Class
应该从xml中选择所有类,除了选择具有名称的类之外的所有类,然后选择该类的所有子类...同样的事情与接口和方法一起...但它根本不起作用!!!! ....没有任何表达式匹配任何东西....
我不能完全依赖绝对路径,因为xml是从源代码动态生成的,因此除了根元素之外的xml内容也会发生变化
答案 0 :(得分:3)
此表达式选择所有嵌套类(示例文档中只有一个:class“FrontPAge”具有嵌套类:
//Class/Class
或使用名称属性
//Class[@name="FrontPAge"]/Class
如果您评估根节点而不是文档(第8行),您的表达式应该有效。如果要对文档进行评估,则第一个元素为<program>
,您必须说
program/Class[@name=\"" + name + "\"]/Class
关闭记录:我使用this online xpath evaluator来验证表达式。只需将示例文档复制到文本字段并使用XPath表达式
即可答案 1 :(得分:2)
我认为您可能需要使用program
启动xpath表达式,因为它是根元素
e.g:
expr = xPath.compile("program/Class[@name=\""+name+"\"]/Interfaces")
我自己没有对此进行测试,但值得一试:)