2013-06-19 3 views
3

Я пишу специальный анализатор/экстрактор данных для какого-то довольно дерьмового HTML.XPath в PHP: получить все текстовые узлы, кроме навигации

Изменение HTML не может быть и речи.

Я пощажу вам детали обручей, которые мне пришлось перепрыгнуть, но теперь я приблизился к своей первоначальной цели. Я использую комбинацию DOMDocument getElementByName, замену регулярных выражений (я знаю, знаю ...) и запросы XPath.

Мне нужно получить весь текст из тела документа. Я бы хотел, чтобы навигация оставалась отдельной сущностью, по крайней мере, в абстрактной форме. Вот что я делаю сейчас:

$contentnodes = $xpath->query("//body//*[not(self::a)]/text()|//body//ul/li/a"); 

foreach ($contentnodes as $contentnode) {  
    $type  = $contentnode->nodeName; 
    $content = $contentnode->nodeValue; 

    $output[] = array($type, $content); 
} 

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

Что XPath синтаксис можно использовать таким образом, что в первой части этого запроса, перед |, я говорю это, чтобы получить все текстовые узлы детей body «s кромеul > li > a.

Обратите внимание, что я не могу полагаться на наличие тегов p или h1 тегов или чего-либо подобного разумного, чтобы сделать обоснованные предположения о содержании.

Благодаря

Update: @ ответ hr_117 в поле ниже работ. Я также обнаружил, что вы можете использовать несколько not заявления так:

//body//text()[not(parent::a/parent::li/parent::ul)][not(parent::h1)]

ответ

2

Вы можете попробовать что-то вроде этого:

//body//text()[not(parent::a/parent::li/parent::ul)]|//body//ul/li/a 
+0

похоже на работу ! Будет проверять его еще немного. Спасибо. – magiclantern

1
//body//*[not(self::a/parent::li/parent::ul)]/text()[normalize-space()]|//body//ul/li/a 

(test)

Смежные вопросы