【问题标题】:JDOM, XPath and Namespace InteractionsJDOM、XPath 和命名空间交互
【发布时间】:2011-03-11 23:56:28
【问题描述】:

我在使用 XPath 表达式从 JDOM 文档中提取一些元素时遇到了非常令人沮丧的事情。这是一个示例 XML 文档 - 我想从文档中完全删除 ItemCost 元素,但我目前无法获取 XPath 表达式来评估任何内容。

  <srv:getPricebookByCompanyResponse xmlns:srv="http://ess.com/ws/srv">
     <srv:Pricebook>
        <srv:PricebookName>Demo Operator Pricebook</srv:PricebookName>
        <srv:PricebookItems>
           <srv:PricebookItem>
              <srv:ItemName>Demo Wifi</srv:ItemName>
              <srv:ProductCode>DemoWifi</srv:ProductCode>
              <srv:ItemPrice>15</srv:ItemPrice>
              <srv:ItemCost>10</srv:ItemCost>
           </srv:PricebookItem>
           <srv:PricebookItem>
              <srv:ItemName>1Mb DIA</srv:ItemName>
              <srv:ProductCode>Demo1MbDIA</srv:ProductCode>
              <srv:ItemPrice>20</srv:ItemPrice>
              <srv:ItemCost>15</srv:ItemCost>
           </srv:PricebookItem>
        </srv:PricebookItems>
     </srv:Pricebook>
  </srv:getPricebookByCompanyResponse>

我通常只使用诸如 //srv:ItemCost 之类的表达式来识别这些元素,这在其他文档上工作得很好,但是在这里它会不断地返回列表中的 0 个节点。这是我一直在使用的代码:

Namespace ns = Namespace.getNamespace("srv","http://ess.com/ws/srv");   
XPath filterXpression = XPath.newInstance("//ItemCost");
filterXpression.addNamespace(ns);   
List nodes = filterXpression.selectNodes(response);

其中 response 是包含上述 XML sn-p 的 JDOM 元素(使用 XMLOutputter 验证)。每当解析此文档时,节点都会不断地具有 size()==0。在同一个文档上使用 Eclipse 中的 XPath 解析器,这个表达式也不起作用。经过一番挖掘,我让 Eclipse 评估程序使用以下表达式://*[local-name() = 'ItemCost'],但是用它替换 Java 代码中的 //srv:ItemCost 仍然没有产生任何结果。我注意到的另一件事是,如果我从 XML 中删除名称空间声明, //srv:ItemCost 将在 Eclipse 解析器中正确解析,但我无法从 XML 中删除它。我现在一直在为我们在这个问题上的时间挠头,并且非常感谢朝着正确的方向轻推。

非常感谢

编辑:固定代码 -

Document build = new Document(response);
XPath filterXpression = XPath.newInstance("//srv:ItemCost");
List nodes = filterXpression.selectNodes(build);

【问题讨论】:

  • 抱歉@Bryn,我知道如何在 C# 中执行此操作,但我没有使用 JDOM 的经验 :( 所以,我删除了我的答案。

标签: java xpath namespaces jdom


【解决方案1】:

确实很奇怪...我在 jdom 方面进行了测试,您的 sn-p 生成了一个空列表,以下工作按预期工作:

public static void main(String[] args) throws JDOMException, IOException {
    File xmlFile = new File("sample.xml");
    SAXBuilder builder = new SAXBuilder();
    Document build = builder.build(xmlFile);        
    XPath filterXpression = XPath.newInstance("//srv:ItemCost");
    System.out.println(filterXpression.getXPath());
    List nodes = filterXpression.selectNodes(build);        
    System.out.println(nodes.size());
}

它产生输出:

//srv:ItemCost
2

【讨论】:

  • 谢谢安德烈亚斯 - 你让我在正确的轨道上。不幸的是,输入是作为已经构建的 JDOM 元素出现的,因此将其序列化以供 SAXBuilder 处理有点 OTT。然而,仅仅通过玩耍似乎所需要的只是将元素包装在一个文档中——现在一切正常。很想知道如果有人能弄清楚为什么?
  • @BrynSadler 将 JDOM Element 包装在 Document 中就足够了,我的一天就这样得救了!非常感谢! :)
猜你喜欢
  • 2010-10-07
  • 2014-03-13
  • 2012-04-02
  • 1970-01-01
  • 2011-02-06
  • 1970-01-01
  • 1970-01-01
  • 2011-08-07
  • 1970-01-01
相关资源
最近更新 更多