我需要使用XPath函数normalized-space()来规范化我想要从X
HTML文档中提取的文本:
http://test.anahnarciso.com/clean_bigbook_0.html
我正在使用以下表达式:
- //*[@slot="address"]/normalize-space(.)
这在我用来测试XPath表达式的Qizx Studio中非常有效.
- let $doc := doc('http://test.anahnarciso.com/clean_bigbook_0.html')
- return $doc//*[@slot="address"]/normalize-space(.)
这个简单的查询返回一系列xs:string.
- 144 Hempstead Tpke
- 403 West St
- 880 Old Country Rd
- 8412 164th St
- 8412 164th St
- 1 Irving Pl
- 1622 McDonald Ave
- 255 Conklin Ave
- 22011 Hempstead Ave
- 7909 Queens Blvd
- 11820 Queens Blvd
- 1027 Atlantic Ave
- 1068 Utica Ave
- 1002 Clintonville St
- 1002 Clintonville St
- 1156 Hempstead Tpke
- Route 49
- 10007 Rockaway Blvd
- 12694 Willets Point Blvd
- 343 James St
现在,我想在我的Java代码中使用前一个表达式.
- String exp = "//*[@slot=\"address"\"]/normalize-space(.)";
- XPath xpath = XPathFactory.newInstance().newXPath();
- XPathExpression expr = xpath.compile(exp);
- Object result = expr.evaluate(doc,XPathConstants.NODESET);
但是最后一行抛出异常:
无法将XPath值转换为Java对象:必需的类是org.w3c.dom.NodeList;提供的值具有类型xs:string
很明显,我应该改变XPathConstants.NODESET;我尝试了XPathConstants.STRING,但它只返回序列的第一个元素.
我怎样才能获得类似Strings数组的东西?
提前致谢.
解决方法
您的表达式在XPath 2.0中有效,但在XPath 1.0(在Java中使用)中是非法的 – 它应该是normalize-space(// * [@ slot =’address’]).
无论如何,在XPath 1.0中,当在节点集上调用normalize-space()时,仅采用第一个节点(按文档顺序).
为了做你想做的事情,你需要使用兼容XPath 2.0的解析器,或者遍历结果节点集并在每个节点上调用normalize-space():
- XPath xpath = XPathFactory.newInstance().newXPath();
- XPathExpression expr;
- String select = "//*[@slot='address']";
- expr = xpath.compile(select);
- NodeList result = (NodeList)expr.evaluate(input,XPathConstants.NODESET);
- String normalize = "normalize-space(.)";
- expr = xpath.compile(normalize);
- int length = result.getLength();
- for (int i = 0; i < length; i++) {
- System.out.println(expr.evaluate(result.item(i),XPathConstants.STRING));
- }