1

我正在尝试使用 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,但这个:

https://twitter.com/?lang=fr

因为它,我得到了这个例外:

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 还是其他问题上。谁能说出代码中有什么问题?任何编辑都会有所帮助。

4

2 回答 2

0

我通常会说来自 XPath 引擎深处的边界索引异常是 XPath 引擎中的错误。唯一需要注意的是 XPath 引擎正在搜索的 DOM 是否存在结构性问题;XPath 处理器有权做出合理的假设,即 DOM 是有效的,如果不是,则崩溃。在这种情况下,这将是创建 DOM 的 Tidy 中的一个错误。

于 2018-11-04T21:46:12.050 回答
0

我在 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");

于 2021-08-24T20:59:35.183 回答