Xpath表达式不会选择任何内容

时间:2011-05-02 07:31:55

标签: java xml xpath

你好, 我有一个动态生成的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内容也会发生变化

2 个答案:

答案 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")

我自己没有对此进行测试,但值得一试:)