需要一些XPath表达式的帮助。一个有效,另一个没有

时间:2009-11-26 22:26:07

标签: java html xpath html-parsing cobra

我正在使用COBRA HTMLParser,但没有运气解析一个特定的标签。这是来源:

<li id="eta" class="hentry">
  <span class="body">
    <span class="actions">
    </span>
    <span class="content">
    </span>
    <span class="meta entry">Content here
    </span>
    <span class="meta entry stub">Content here
    <span class="shared-content">
      Information by
      <a class="title" data="associate" href="/associate">Associate</a>
    </span>
    </span>
  </span>
</li>

我可以使用以下XPath来获取正确的信息:

            XPath xpath = XPathFactory.newInstance().newXPath();
            NodeList nodeList = (NodeList) xpath.evaluate("//span[contains(@class, 'body')]", document, XPathConstants.NODESET);
            int length = nodeList.getLength();
            System.out.println(nodeList.getLength());
            for(int i = 0; i < length; i++) {
                Element element = (Element) nodeList.item(i);
                NodeList n = null;
                try {
                    n = (NodeList) xpath.evaluate("span[contains(@class, 'content')]", element, XPathConstants.NODESET);
                    String body = n.item(0).getTextContent();
                    System.out.println("Content: " + body);
                } catch (Exception e) {};

                try {

                    String date = (String) xpath.evaluate("span[contains(@class, 'meta entry')]/a/span/@data", element, XPathConstants.STRING);
                    System.out.println("DATA: " + date);

                    String source = (String) xpath.evaluate("//span[contains(@class, 'meta entry')]/span", element, XPathConstants.STRING);
                    System.out.println("DATA: " + source);

                } catch (Exception e) {};

                //This does not work at all! I've tried every combination and still can't get it to run
                try {
                    String info = (String) xpath.evaluate("//span[@class='shared-content']/a/@data", element, XPathConstants.STRING);
                    System.out.println("INFO: " + info);
                } catch (Exception e) {};

            }

最后一个表达式无论我尝试什么组合都不起作用。我也试过以下但是没有用,

        String info = (String) xpath.evaluate("//span[contains(@class, 'shared-content')]/a/@data", element, XPathConstants.STRING);
        String info = (String) xpath.evaluate("//span[contains(@class, 'meta entry info')]/span/a/@data", element, XPathConstants.STRING);

有什么建议吗?

编辑:有一些关于XML是非法的建议(说实话,我不确定为什么它是非法的,因为我到目前为止几乎到处都看到它)但我无法控制虽然是XML(至少到星期一,直到我的其他伙伴回来)。我试图看到编写包含此信息的mashup的可行性。有没有办法禁用检查或什么?

这是解析的XML:

       <?xml version="1.0" encoding="UTF-8"?>
          <span class="body">
            <span class="content">TextContent</span>
            <span class="meta entry">TextContent</span>

          </span>

我猜这个文档没有被正确解析。

4 个答案:

答案 0 :(得分:2)

XPathVisualizer是一个很好的XPath Visualizer工具,在Windows上运行,可以让你看到XPath查询的结果。 Xcopy安装,单个EXE文件。自由。

我接过它并在其中运行您的查询,得到了这个结果:

alt text

答案 1 :(得分:1)

@ Jherico,@ Andrew Keith 我不知道COBRA HTMLParser,但将#PCDATA与内部节点相结合是一种合法的XML格式 这可以在DTD中定义如下:

<!ELEMENT text_node     (#PCDATA|i|b|u)*>

这是格式良好的HTML仍然是合法XML的方式。

答案 2 :(得分:0)

我运行了以下代码

public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException, XPathExpressionException {
    Document doc = XmlUtil.parseXmlResource("/temp.xml");
    for (Node n : XPathUtil.getNodes(doc, "//span[contains(@class, 'body')]")) {
        System.out.println(XPathUtil.getStringValue(doc, "//span[@class='shared-content']/a/@data"));
    }
}

输出'associate'。我认为你的XPath很好。发生了什么事呢?你可以删除空的catch块,这样我们就可以看到你是否真的得到异常吗?

注意,XmlUtil和XPathUtil是我自己的个人便利函数,可以消除大多数XPath和XML样板代码。

答案 3 :(得分:0)

我只是按原样运行代码示例(复制粘贴)并获得此输出。所以一切似乎都很好。 (你使用哪种眼镜蛇版本?Me 0.98.4)

1
Content:

DATA:
DATA:
      Information by
      Associate

INFO: associate

可重复测试(?)

  • 使用javac / java版本1.6.0_16(HotSpot客户端:build 14.2-b01,混合模式,共享)
  • 我从这里下载了0.98.4( cobra-0.98.4.zip Sourceforge: Cobra HTML Toolkit download
  • js.jar 中提取 cobra.jar cobra-0.98.4.zip:\lib 到目录{{1} }
  • 在同一目录中写了XMLTest.javaHTMLTest.java!filenames is links to source)
  • 将其转为编译(窗口):XXX
  • 然后像这样执行(包括输出)

的XMLTest

javac -cp .;cobra.jar;js.jar *.java

XMLTest输出:

java -cp .;cobra.jar;js.jar XMLTest 1

HTMLTest

1
Content:

DATA:
DATA:
      Information by
      Associate

INFO: associate 

HTMLTest输出:

java -cp .;cobra.jar;js.jar HTMLTest 1