JDOM、XPath 和命名空间交互
我在使用 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 片段的 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);
I'm having a very frustrating time extracting some elements from a JDOM document using an XPath expression. Here's a sample XML document - I'd like to remove the ItemCost elements from the document altogether, but I'm having trouble getting an XPath expression to evaluate to anything at the moment.
<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>
I would normally just use an expression such as //srv:ItemCost to identify these elements, which works fine on other documents, however here it continually returns 0 nodes in the List. Here's the code I've been using:
Namespace ns = Namespace.getNamespace("srv","http://ess.com/ws/srv");
XPath filterXpression = XPath.newInstance("//ItemCost");
filterXpression.addNamespace(ns);
List nodes = filterXpression.selectNodes(response);
Where response is a JDOM element containing the above XML snippet (verified with an XMLOutputter). nodes continually has size()==0 whenever parsing this document. Using the XPath parser in Eclipse on the same document, this expression does not work either. After some digging, I got the Eclipse evaluator to work with the following expression: //*[local-name() = 'ItemCost'], however replacing the //srv:ItemCost in the Java code with this still produced no results. Another thing I noticed is if I remove the namespace declaration from the XML, //srv:ItemCost will resolve correctly in the Eclipse parser, but I can't remove it from the XML. I've been scratching my head for ours hours on this one now, and would really appreciate some nudging in the right direction.
Many thanks
Edit : Fixed code -
Document build = new Document(response);
XPath filterXpression = XPath.newInstance("//srv:ItemCost");
List nodes = filterXpression.selectNodes(build);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
确实很奇怪...我用 jdom 进行了测试,您的代码片段生成了一个空列表,以下内容按预期工作:
它生成输出:
Strange, indeed... I tested on my side with jdom, and your snippet produced an empty list, the following works as intended:
It produces the output: