Этот вопрос был перефразирован.Я использую модули CPAN Perl WWW :: Mechanize для навигации по сайту, HTML :: TreeBuilder-XPath для захвата содержимого и xacobeo для проверки моего кода XPath.на HTML / XML.Цель состоит в том, чтобы вызвать этот сценарий Perl с веб-сайта на основе PHP и загрузить извлеченное содержимое в базу данных.Поэтому, если контент «отсутствует», его все равно необходимо учитывать.
Ниже приведен проверенный сокращенный пример кода, изображающий мою задачу.Примечание:
- Эта страница заполнена динамически и содержит различные
ITEMS
, выведенные для разных магазинов;различное количество Products*
будет существовать для каждого магазина.И эти списки продуктов могут иметь или не иметь под ними детализированную таблицу. - Захваченные данные должны быть в массивах, и необходимо поддерживать связь любого детализированного списка (если он существует) с перечнем продуктов.,
Ниже пример xml изменяется для магазина (как описано выше), но для краткости я показываю только один «тип» выходных данных.Я понимаю, что все данные могут быть собраны в один массив, а затем регулярное выражение используется для расшифровки контента с целью загрузки его в базу данных.Я ищу более глубокие знания XPath, чтобы помочь упростить это (и будущее) решение (я).
<!DOCTYPE XHTML>
<table id="8jd9c_ITEMS">
<tr><th style="color:red">The Products we have in stock!</th></tr>
<tr><td><span id="Product_NUTS">We have nuts!</span></td></tr>
<tr><td>
<!--Table may or may not exist -->
<table>
<tr><td style="color:blue;text-indent:10px">Almonds</td></tr>
<tr><td style="color:blue;text-indent:10px">Cashews</td></tr>
<tr></tr>
</table>
</td></tr>
<tr><td><span id="Product_VEGGIES">We have veggies!</span></td></tr>
<tr><td>
<!--Table may or may not exist -->
<table>
<tr><td style="color:blue;text-indent:10px">Carrots</td></tr>
<tr><td style="color:blue;text-indent:10px">Celery</td></tr>
<tr></tr>
</table>
</td></tr>
<tr><td><span id="Product_ALCOHOL">We have booze!</span></td></tr>
<!--In this case, the table does not exist -->
</table>
Оператор XPath:
'//table[contains(@id, "ITEMS")]/tr[position() >1]/td/span/text()'
найдет:
We have nuts!
we have veggies!
We have booze!
И оператор XPath:
'//table[contains(@id, "ITEMS")]/tr[position() >1]/td/table/tr/td/text()'
найдет:
Almonds
Cashews
Carrots
Celery
Можно объединить два оператора XPath:
'//table[contains(@id, "ITEMS")]/tr[position() >1]/td/span/text() | //table[contains(@id, "ITEMS")]/tr[position() >1]/table/tr/td/text()'
Чтобы найти:
We have nuts!
Almonds
Cashews
We have veggies!
Carrots
Celery
We have booze!
Опять же, вышеупомянутый массив может быть расшифрован (в реальном коде) для его связи продукта с списком с помощью регулярных выражений. Но может ли массив быть построен с использованием XPath таким образом, чтобы сохранить эту связь?
Например (псевдо-речь, это не работает):
'//table[contains(@id, "ITEMS")]/tr[position()>1]/td/span/text() |
if exists('//table[contains(@id, "ITEMS")]/tr[position() >1]/table))
then ("NoTable") else ("TableRef") |
Save this result into @TableRef ('//table[contains(@id, "ITEMS")]/tr[position() >1]/table/tr/td/text()')'
Невозможно построить многомерные массивы (в традиционном смысле) в Perl, см. perldoc perlref Но, надеюсь, решение, подобное приведенному выше, может создать что-то вроде:
@ITEMS[0] => We have nuts!
@ITEMS[1] => nutsREF <-- say, the last word of the span value + REF
@ITEMS[2] => We have veggies!
@ITEMS[3] => veggiesREF <-- say, the last word of the span value + REF
@ITEMS[4] => We have booze!
@ITEMS[5] => NoTable <-- value accounts for the missing info
@nutsREF[0] => Almonds
@nutsREF[1] => Cashews
@veggiesREF[0] => Carrots
@veggiesREF[1] => Celery
В реальном коде продукты известны, поэтому my @veggiesREF
и my @nutsREF
могут быть определены в ожидании вывода XPath.
Я понимаю, что XPath if / else / then работает в версии XPath 2.0,Я нахожусь в системе Ubuntu и работаю локально, но я все еще не ясно, использует ли мой сервер apache2 его или версию 1.0.Как мне это проверить?
Наконец, если вы можете показать, как вызывать скрипт Perl из отправки формы PHP И как передавать массив Perl в вызывающую функцию PHP, то это будет способствовать получению вознаграждения.:)
Спасибо!
ЗАКЛЮЧИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ:
Комментарии непосредственно под этим постом были направлены на первоначальный пост, который был слишком расплывчатым.На последующую повторную публикацию (и награду) ikegami отреагировал очень креативно, что решило проблему псевдо, но оказалось трудным для понимания и повторного использования в моем реальном приложении, что влечет за собой многократное использование на различных html-страницах.Примерно в 18-м комментарии в нашем диалоге я наконец обнаружил его значение и использование ($ cat) - недокументированного синтаксиса Perl, который он использовал.Для новых читателей понимание этого синтаксиса позволяет понять (и переформатировать) его разумное решение проблемы.Его пост, безусловно, отвечает основным требованиям, предъявляемым в ОП, но для этого не используется HTML :: TreeBuilder :: XPath.
jpalecek использует HTML :: TreeBuilder :: XPath, но не помещает захваченные данные в массивы для передачи обратно в функцию PHP и загрузки в базу данных.
Я узнал от обоих респондентови надеюсь, что этот пост поможет другим новичкам в Perl, таким как я.Будем весьма признательны за любые окончательные материалы.