Нужна помощь с выражением XPath. Один работает, другой нет - PullRequest
0 голосов
/ 27 ноября 2009

Я использую HTML-парсер COBRA, но мне не повезло при разборе одного конкретного тега. Вот источник:

<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 (по крайней мере до понедельника, пока мои друзья не вернутся). Я пытаюсь увидеть возможность написания коллажей, включая эту информацию. Есть ли способ отключить проверку или что-то еще?

Вот проанализированный XML:

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

          </span>

Полагаю, документ не обрабатывается правильно.

Ответы [ 4 ]

2 голосов
/ 27 ноября 2009

XPathVisualizer - это прекрасный инструмент XPath Visualizer, работающий в Windows, позволяющий просматривать результаты ваших запросов XPath. Xcopy установить, один файл EXE. Свободно.

Я взял и запустил ваш запрос, получил такой результат:

alt text

1 голос
/ 27 ноября 2009

@ Jherico, @ Andrew Keith Я не знаю HTMLParser COBRA, но объединение #PCDATA с внутренними узлами является допустимым форматом XML.
Это можно определить следующим образом в DTD:

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

Именно так хорошо отформатированный HTML по-прежнему является допустимым XML.

0 голосов
/ 27 ноября 2009

Я просто запустил ваш пример кода как есть (копировать, вставить) и получил этот вывод. Так что все в порядке. (какую версию кобры вы используете? Me 0.98.4)

1
Content:

DATA:
DATA:
      Information by
      Associate

INFO: associate

Воспроизводимый тест (?)

  • Использование javac / java версии 1.6.0_16 (клиент HotSpot: сборка 14.2-b01, смешанный режим, совместное использование)
  • Я скачал 0,98,4 (cobra-0.98.4.zip) отсюда Sourceforge: Cobra HTML Toolkit скачать
  • Извлечено js.jar и cobra.jar из cobra-0.98.4.zip:\lib в каталог XXX
  • Написал XMLTest.java и HTMLTest.java в том же каталоге (! Имена файлов являются ссылками на источник)
  • Запустил это для компиляции (windows): javac -cp .;cobra.jar;js.jar *.java
  • Затем выполняется так (вывод включен)

XMLTest

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

Вывод XMLTest:

1
Content:

DATA:
DATA:
      Information by
      Associate

INFO: associate 

HTMLTest

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

Вывод HTMLTest:

1
Content:

DATA:
DATA:
      Information by
      Associate

INFO: associate
0 голосов
/ 27 ноября 2009

Я запустил следующий код

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"));
    }
}

И это выводит «ассоциировать». Я думаю, что ваш XPath в порядке. Что происходит вместо этого? И можете ли вы удалить пустые блоки catch, чтобы мы могли видеть, действительно ли вы получаете исключения?

Обратите внимание, что XmlUtil и XPathUtil - это мои собственные персональные удобные функции для устранения большей части стандартного кода XPath и XML.

...