Извлечение полного узла с дочерними узлами с использованием XPath

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

Пример HTML

<body>
    <div>
      At first glance you may ask, &#8220;what <i>exactly</i>
      do you mean?&#8221; It means that we want to help <b>you</b> figure...
    </div>
</body>

У меня есть следующий XPath

/body/div

Я получаю следующее

At first glance you may ask, &#8220;what do you mean?&#8221; It means that we want to help figure...

Я хочу

At first glance you may ask, &#8220;what <i>exactly</i> do you mean?&#8221; It means that we want to help <b>you</b> figure...

Если вы заметили, что в примере HTML есть HTML-теги <i/> и <b /> в содержимом. Слова внутри этих тегов «теряются», когда я извлекаю содержимое.

Я использую SimpleXML в PHP, если это имеет значение.


person null    schedule 14.10.2009    source источник
comment
Я не могу воспроизвести ваш результат. Как с помощью echo $result (т.е. приведения симплексного элемента к строке), так и с помощью -›asXML() я получаю внутренние теги на выходе. Можете ли вы предоставить фактический тестовый код?   -  person VolkerK    schedule 14.10.2009
comment
Итак, я конвертировал в HTML, а затем загружал его в SimpleXML... отредактировал вопрос, чтобы отразить это.   -  person null    schedule 14.10.2009


Ответы (3)


Ваш XPath в порядке, хотя вы можете удалить последний /., поскольку он излишен:

/atom/content

Весь HTML находится внутри раздела <![CDATA ]]>, поэтому в XML DOM у вас фактически есть только текст. Теги <i> и <b> не будут обрабатываться как теги, а просто будут отображаться как текст. Использование раздела CDATA точно такое же, как если бы ваш XML был написан следующим образом:

<atom>
    <content>
      At first glance you may ask, &amp;#8220;what &lt;i&gt;exactly&lt;/i&gt;
      do you mean?&amp;#8221; It means that we want to help &lt;b&gt;you&lt;/b&gt; figure...
    </content>
</atom>

Итак, что бы вы ни делали с элементом <content> впоследствии, эти теги удаляются. Вы позже анализируете текст как HTML, пропускаете его через фильтр или что-то в этом роде?

person John Kugelman    schedule 14.10.2009
comment
Удалена конечная точка... однако вопрос несколько изменился. - person null; 14.10.2009
comment
Я не думаю, что проблема в XPath, поэтому можете ли вы опубликовать свой PHP-код? - person John Kugelman; 14.10.2009

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

Вы можете использовать asXML() для каждого элемента div, а затем удалить теги div, или вы можете преобразовать элементы div в DOMNodes, затем перебрать $div->childNodes и сериализовать каждый дочерний элемент. Обратите внимание, что ваши объекты HTML, скорее всего, будут заменены фактическими символами, если они доступны.

Кроме того, вы можете ознакомиться с проектом SimpleDOM и использовать его метод innerHTML().

$html = 
'<body>
    <div>
      At first glance you may ask, &#8220;what <i>exactly</i>
      do you mean?&#8221; It means that we want to help <b>you</b> figure...
    </div>
</body>';

$body = simpledom_load_string($html);

foreach ($body->xpath('/body/div') as $div)
{
    var_dump($div->innerHTML());
}
person Josh Davis    schedule 12.11.2009

Я не знаю, отличается ли SimpleXML, но мне кажется, что вам нужно убедиться, что вы выбираете все типы узлов, а не только текст. В стандартном XPath вы бы сделали /body/div/node()

person Chris Cameron-Mills    schedule 14.10.2009