我尝试解析看起来像的xml
<EvaluateHandRequest xmlns="http://www.aaa.com/aaa/schemas">
<card>
<suit>HEARTS</suit>
<face>TEN</face>
</card>
<card>
<suit>SPADES</suit>
<face>KING</face>
</card>
<card>
<suit>HEARTS</suit>
<face>KING</face>
</card>
<card>
<suit>DIAMONDS</suit>
<face>TEN</face>
</card>
<card>
<suit>CLUBS</suit>
<face>TEN</face>
</card>
</EvaluateHandRequest>
为此,我使用了XPathExpression,但是我无法提取结果。
SAXBuilder jdomBuilder = new SAXBuilder();
Document jdomDocument = jdomBuilder.build(xmlSource);
Element element = jdomDocument.getRootElement();
XPathFactory xFactory = XPathFactory.instance();
XPathExpression xExpression = xFactory.compile("/*/*");
List<Element> list = xExpression.evaluate(element);
System.out.println(list.size() + " " + list.get(0).getName());//5 card
for (Element element2 : list) {
System.out.println(element2.getValue()); //proper result
}
如果我在编译过程中使用
/*/*
表达式,则会得到所有卡及其值,其中card
位于层次结构的顶部。但是当我使用
/*/card
时,我从那里没有任何元素。如果我在表达式中写任何节点的任何名称,我将无法获得任何结果。
我有什么问题?
最佳答案
XPath表达式始终支持名称空间。这就是它们的指定方式(section 2.3-强调我的):
使用以下命令将节点测试中的QName扩展为扩展名:
表达式上下文中的名称空间声明。这是一样的
起始标签和结束标签中元素类型名称的扩展方式
除了不使用通过xmlns声明的默认名称空间:if
QName没有前缀,则名称空间URI为null(此
与属性名称的扩展方式相同)。如果
QName有一个前缀,在该前缀中没有名称空间声明
表达式上下文。
因此,在解决这个问题之前,您需要指定要使用的命名空间...。但是,让我们来看一下在您工作正常的XPath中的用法:
XPathExpression xExpression = xFactory.compile("/*/*");
List<Element> list = xExpression.evaluate(element);
那不应该编译。。。XPathExpression是一个泛型类。您希望它返回Elements ...要正确执行此操作,您需要在compile方法中向结果添加过滤器。考虑您当前的行:
XPathExpression xExpression = xFactory.compile("/*/*");
应该是:
XPathExpression<Element> xExpression = xFactory.compile("/*/*", Filters.element());
这将使所有内容进行编译,而不会出现任何错误或警告...
现在,要扩展XPath表达式以仅提取
card
元素,我们需要包括名称空间:Namespace aaa = Namespace.getNamespace("aaa", "http://www.aaa.com/aaa/schemas");
例如,仅获取西服元素:
Namespace aaa = Namespace.getNamespace("aaa", "http://www.aaa.com/aaa/schemas");
XPathExpression<Element> xExpression = xFactory.compile(
"/*/aaa:card/aaa:suit", Filters.element(), null, aaa);
如果需要多个名称空间,则可以添加它们。
请注意,名称空间声明使用前缀
aaa
,即使XML文档中没有使用前缀,您仍然需要一个前缀来引用XPath中的名称空间。仅仅因为您的文档中没有前缀并不意味着就没有名称空间。阅读Javadoc for
compile(...)
关于java - jdom2 xPathExpression拉节点失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29060789/