Использование регулярных выражений для фильтрации атрибутов в xpath с помощью php - PullRequest
2 голосов
/ 26 июля 2011

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

        $this->xpath = new DOMXPath($this->dom); 
            $this->xpath->registerNamespace("php", "http://php.net/xpath");
            $this->xpath->registerPHPFunctions();
        foreach($xpath->query("//table[php:function('preg_match', '/post\d+/', @id)]") as $key => $row)
    {

}

Ошибка, которую я получаю: preg_match ожидает, что вторым параметром будет строка, заданный массив.

Ответы [ 2 ]

2 голосов
/ 26 июля 2011

Что я делаю не так?

Выражение xpath @id (второй параметр) возвращает массив, но preg_match ожидает строку.

Сначала преобразуйте его в строку: string(@id).

Рядом с этим вам нужно сравнить результат с 1, так как preg_match возвращает 1 при обнаружении:

foreach($xpath->query("//table[@id and 1 = php:function('preg_match', '/post\d+/', string(@id))]") as $key => $row)
{
    var_dump($key, $row, $row->ownerDocument->saveXml($row));
}

Объяснение / что здесь происходит?:

Выражение xpath по умолчанию возвращает список узлов (точнее, набор узлов). Если вы отображаете функцию PHP на такие выражения, эти наборы представляются в виде массива. Вы можете легко проверить это, используя var_dump:

$xpath->query("php:function('var_dump', //table)");

array(1) {
  [0]=>
  object(DOMElement)#3 (0) {
  }
}

То же самое для выражения xpath @id в контексте каждого элемента таблицы:

$xpath->query("//table[php:function('var_dump', @id)]");

array(1) {
  [0]=>
  object(DOMAttr)#3 (0) {
  }
}

Вы можете изменить это на строковый результат, используя функцию xpath string :

Набор узлов преобразуется в строку, возвращая строковое значение узла в наборе узлов, который находится первым в порядке документов. Если набор узлов пуст, возвращается пустая строка.

$xpath->query("//table[php:function('var_dump', string(@id))]");

string(4) "test"

(в таблице id="test")

2 голосов
/ 26 июля 2011

Атрибут по-прежнему является сложным элементом в соответствии с DOM (имеет пространство имен и т. Д.). Использование:

//table[php:function('preg_match', '/post\d+/', string(@id))]

Теперь нам нужен логический возврат, поэтому:

function booleanPregMatch($match,$string){
    return preg_match($match,$string)>0;
}
$xpath->registerPHPFunctions();
foreach($xpath->query("//table[@id and php:function('booleanPregMatch', '/post\d+/', string(@id))]") as $key => $row){
     echo $row->ownerDocument->saveXML($row);
}

Кстати: для более сложных вопросов вы, конечно, можете незаметно проверить, что происходит с этим:

//table[php:function('var_dump',@id)]

Жаль, что у нас нет доступных функций XPATH 2.0, но если вы справитесь с этим требованием с более ненадежным starts-with, я бы всегда предпочел это, а не импортировать функции PHP.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...