提问人:A Beginner 提问时间:11/5/2018 最后编辑:A Beginner 更新时间:8/25/2021 访问量:672
在 Java 中计算 XPath 表达式时出现异常
Getting Exception on evaluating an XPath expression in Java
问:
我正在尝试在 Java 中学习 Xpath 表达式的用法。我正在使用 Jtidy 将 HTML 页面转换为 XHTML,以便我可以使用 XPath 表达式轻松解析它。我有以下代码:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = ConvertXHTML("https://twitter.com/?lang=fr");
//Create XPath
XPathFactory xpathfactory = XPathFactory.newInstance();
XPath Inst= xpathfactory.newXPath();
NodeList nodes = (NodeList)Inst.evaluate("//p/@align",doc,XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); ++i)
{
Element e = (Element) nodes.item(i);
System.out.println(e);
}
public Document ConvertXHTML(String link){
try{
URL u = new URL(link);
BufferedInputStream instream=new BufferedInputStream(u.openStream());
FileOutputStream outstream=new FileOutputStream("out.xhtml");
Tidy c=new Tidy();
c.setShowWarnings(false);
c.setInputEncoding("UTF-8");
c.setOutputEncoding("UTF-8");
c.setXHTML(true);
return c.parseDOM(instream,outstream);
}
它适用于大多数 URL,但这个:
我因此而出现此异常:
javax.xml.transform.TransformerException:索引 -1 越界.....
以下是我得到的堆栈跟踪的一部分:
javax.xml.transform.TransformerException: Index -1 out of bounds for length 128
at java.xml/com.sun.org.apache.xpath.internal.XPath.execute(XPath.java:366)
at java.xml/com.sun.org.apache.xpath.internal.XPath.execute(XPath.java:303)
at java.xml/com.sun.org.apache.xpath.internal.jaxp.XPathImplUtil.eval(XPathImplUtil.java:101)
at java.xml/com.sun.org.apache.xpath.internal.jaxp.XPathExpressionImpl.eval(XPathExpressionImpl.java:80)
at java.xml/com.sun.org.apache.xpath.internal.jaxp.XPathExpressionImpl.evaluate(XPathExpressionImpl.java:89)
at files.ExampleCode.GetThoselinks(ExampleCode.java:50)
at files.ExampleCode.DoSomething(ExampleCode.java:113)
at files.ExampleCode.GetThoselinks(ExampleCode.java:81)
at files.ExampleCode.DoSomething(ExampleCode.java:113)
我不确定问题出在网站转换后的 xhtml 还是其他方面。谁能说出代码中有什么问题?任何编辑都会有所帮助。
答:
0赞
Michael Kay
11/5/2018
#1
我通常会说,来自 XPath 引擎深处的边界索引异常是 XPath 引擎中的错误。唯一需要注意的是,XPath 引擎正在搜索的 DOM 是否存在结构错误;XPath 处理器有权合理地假设 DOM 是有效的,如果 DOM 无效,则崩溃。在这种情况下,这将是 Tidy 中的一个错误,它创建了 DOM。
评论
0赞
A Beginner
11/5/2018
假设问题出在 Tidy 中,它没有给我一个合适的 XHTML。有什么方法可以在 Xpath 中进行检查,以便它可以避免空节点评估?
0赞
Michael Kay
11/5/2018
我认为我在这个阶段的策略是 (a) 构建一个包含 Apache XPath 和 Tidy 项目源代码的项目,尝试重现崩溃并调试它,或者 (b) 切换到替代库,例如 validator.nu 而不是 Tidy、Saxon 或 Jaxen 代替 Apache XPath。您也可以尝试 (c) 从支持库的人那里获得帮助,但对于 XPath 库,我不会屏住呼吸。
0赞
user3969107
8/25/2021
#2
我在JTidy生成的文档上使用xpath评估时遇到了类似的问题。我通过让JTidy将它生成的DOM序列化为一个文件,然后使用javax.xml.parsers.DocumentBuilder解析该xml文件来获得DOM的第二个版本来解决它。 看起来很奇怪,使用第二个避免了越界异常并起作用。使用如下所示的代码:
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
// If you don't do the following, it will take a full minute to parse the xml document (presumably the time-out
// period for trying to load the DTD). See https://stackoverflow.com/questions/6204827/xml-parsing-too-slow.
documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document doc = tidy.parseDOM(input, null);
FileOutputStream fos = new FileOutputStream("temp.xml");
tidy.pprint(doc, fos);
fos.close();
doc = documentBuilder.parse("temp.xml");
评论