Извлечение содержимого на основе XPATH из HTML-страниц - PullRequest
0 голосов
/ 29 июля 2010

Я пытаюсь извлечь контент на основе заданного xpath.Когда это только один элемент, который я хочу извлечь, это не проблема.Когда у меня есть список элементов, соответствующих этому xpath, я получаю список узлов и могу извлечь значения.

Однако есть пара элементов, связанных друг с другом, образующих группу, и эта группа повторяется.

Один из способов, который я мог бы сделать, - это получить список узлов родительского узла всех таких групп, а затем применить технику синтаксического анализа на основе SAX для извлечения информации.Но это привело бы к кодированию конкретного шаблона.Я хочу сделать это общим.напр.

<html><body>
<!--... a lot divs and other tags ... -->
<div class="divclass">
<item>
     <item_name>blah1</item_name>
     <item_qty>1</item_qty>
     <item_price>100</item_price>
</item>
</div>
<div class="divclass">
<item>
     <item_name>blah2</item_name>
     <item_qty>2</item_qty>
     <item_price>200</item_price>
</item>
</div>
<div class="divclass">
<item>
     <item_name>blah3</item_name>
     <item_qty>3</item_qty>
     <item_price>300</item_price>
</item>
</div>
</body></html>

Я мог бы легко написать код для this xml, но не универсальный, который мог бы анализировать любую заданную спецификацию.

Я должен быть в состоянии создатьlist из map из attribute-value сверху.

Кто-нибудь пробовал это?

EDIT Список входных путей:

1. "html:div[@class='divclass']/item/item_name"
2. "html:div[@class='divclass']/item/item_qty"
3. "html:div[@class='divclass']/item/item_price"

Ожидаемый вывод в виде простого текста:

 item_name:blah1;item_qty:1;item_price:100
 item_name:blah2;item_qty:2;item_price:200
 item_name:blah3;item_qty:3;item_price:300

Ключевым моментом здесь является то, что, если я применю каждый xpath отдельно, он будет извлекать мне результаты по вертикали, то есть первый получит все item_names, второй получит все qtys.Так что я потеряю взаимосвязь внутри этих частей.

Надеюсь, это очистит мои требования.

Спасибо, Найн

Ответы [ 5 ]

3 голосов
/ 21 августа 2010

Я не уверен, что получил ваш вопрос, но похоже, что вы хотите использовать XPath для документов HTML.

Чтобы использовать XPath, рассматриваемый HTML-документ должен быть правильно сформирован.Существует несколько парсеров HTML для Java; эта статья сравнивает 4 из них.

HtmlCleaner , кажется, обеспечивает то, что вы ищете.Это позволяет выполнять подмножество XPath для «очищенных» HTML-документов.Очевидно, он не поддерживает полный набор выражений XPath, однако, смотрите документацию .

Если вам требуется более сложное выражение XPath, чем то, что поддерживает HtmlCleaner, вам может понадобиться использовать javax.xml.xpath пакет с правильно сформированным документом XHTML. JTidy может конвертировать HTML-документ в XHTML.

Надеюсь, это ответ на ваш вопрос.

2 голосов
/ 25 августа 2010

Я думаю, что XQuery - отличное решение для очистки экрана.Вы можете использовать процессор Saxon для выполнения ваших xqueries.Более того, вы можете использовать расширение Piggy Bank Firefox, чтобы легко находить выражения XPath, относящиеся к содержимому, которое вы хотите извлечь с веб-страницы, которое вы можете использовать в своих xqueries.

1 голос
/ 25 августа 2010

Почему бы не применить XPath в два этапа.

Сначала XPath (s), чтобы получить записи (строки в вашем выводе):

//div[@class='divclass']/item

Затем XPath (s) для получения полей (столбцов), относящихся к каждой записи:

item_name
item_qty
item_price

Вот рабочий код (в сценариях Javascript, Windows), который дает желаемый результат:

var doc = new ActiveXObject("MSXML.DOMDocument");
doc.load("test.xml");

// XPATH #1
var recordXPath = "//div[@class='divclass']/item";
// XPATHS #2, in a dictionary ("field name":"XPath")
var fieldXPaths = { item_name : "item_name",
                    item_qty : "item_name",
                    item_price : "item_price" };

var items = doc.selectNodes(recordXPath);
for (var itemCtr = 0; itemCtr < items.length; itemCtr++) {
    var item = items[itemCtr];
    var fieldEntries = [];

    for (var fieldName in fieldXPaths) {
        var fieldXPath = fieldXPaths[fieldName];
        var fieldNode = item.selectSingleNode(fieldXPath);
        fieldEntries.push(fieldNode.tagName + ":" + fieldNode.text);
    }
    WScript.Echo(fieldEntries.join(";"));
}
0 голосов
/ 26 августа 2010

Не знаю, помогает ли это, но я использую XSLT, чтобы перейти от данных к HTML. Мне кажется, что вам просто нужно немного структурировать выполнение XPATH, и XSLT хорош для этого.

0 голосов
/ 29 июля 2010

Я не понимаю, чего вы хотите достичь и как это связано с XPath. Если вы хотите отобразить XML на объекты Java, может помочь JAXB , но он основан на схемах XML, а не на XPath.

...