Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Оси xPath
Форумы портала PHP.SU » » XML и его обработка » Оси xPath

Страниц (1): [1]
 

1. armancho7777777 - 20 Сентября, 2013 - 16:23:09 - перейти к сообщению
Всем привет!
Задача в следующем:
надо выбрать всех родителей элементов в html документе,
которые в свою очередь являются первыми потомками своих родителей (first-child (не first)).
Запрос ниже выбирает всех родителей:
PHP:
скопировать код в буфер обмена
  1.  
  2. $xPath->query(
  3.         '(' .
  4.         '/html/body/div/div/div[1]/div/p[1]/ancestor::*|' .
  5.         '/html/body/div/div/div[1]/div/p[2]/ancestor::*|' .
  6.         '/html/body/div/div/div[2]/div/div/p[1]/ancestor::*|' .
  7.         '/html/body/div/div/div[2]/div/div/p[2]/ancestor::*|' .
  8.         '/html/body/div/div/div[3]/div/div/p[1]/ancestor::*|' .
  9.         '/html/body/div/div/div[3]/div/div/p[2]/ancestor::*' .
  10.         ')'
  11. );
  12.  
2. armancho7777777 - 21 Сентября, 2013 - 01:01:25 - перейти к сообщению
Решение:

PHP:
скопировать код в буфер обмена
  1.  
  2. class Filter {
  3.        
  4.         public static function firstChild($node) {
  5.                 return (self::__getFirst($node[0]->parentNode->childNodes) === $node[0]);
  6.         }
  7.  
  8.         private static function __getFirst($nodeList)
  9.         {
  10.                 foreach($nodeList as $child) {
  11.                         if($child->nodeType == 1)
  12.                         return $child;
  13.                 }
  14.                
  15.                 return NULL;
  16.         }
  17. }
  18.  
  19. $xpath = new \DOMXpath($document);
  20.  
  21. $xpath->registerNamespace("php", "http://php.net/xpath");
  22.  
  23. foreach(get_class_methods('Filter') as $methodName) {
  24.         $xpath->registerPHPFunctions("Filter::" . $methodName);
  25. }
  26.  
  27. $path = (
  28.         '/html/body/div/div/div[1]/div/p[1]/ancestor::*|' .
  29.         '/html/body/div/div/div[1]/div/p[2]/ancestor::*|' .
  30.         '/html/body/div/div/div[2]/div/div/p[1]/ancestor::*|'.
  31.         '/html/body/div/div/div[2]/div/div/p[2]/ancestor::*|'.
  32.         '/html/body/div/div/div[3]/div/div/p[1]/ancestor::*|'.
  33.         '/html/body/div/div/div[3]/div/div/p[2]/ancestor::*'
  34. );
  35.  
  36. $xpath = $xpath->query('(' . $path . ')[php:function("Filter::firstChild", self::*)]');
  37.  
  38.  
3. armancho7777777 - 21 Сентября, 2013 - 03:28:45 - перейти к сообщению
Ещё решение (чисто на осях):
PHP:
скопировать код в буфер обмена
  1.  
  2. $path = (
  3.         '(' .
  4.         '/html/body/div/div/div[1]/div/p[1]/ancestor::*|' .
  5.         '/html/body/div/div/div[1]/div/p[2]/ancestor::*|' .
  6.         '/html/body/div/div/div[2]/div/div/p[1]/ancestor::*|'.
  7.         '/html/body/div/div/div[2]/div/div/p[2]/ancestor::*|'.
  8.         '/html/body/div/div/div[3]/div/div/p[1]/ancestor::*|'.
  9.         '/html/body/div/div/div[3]/div/div/p[2]/ancestor::*' .
  10.         ')'
  11. );
  12.  
  13. $xPath->query($path . '[parent::*/*[1] = self::* or not(parent::*)]');
  14.  


(Добавление)
На большом документе второй вариант почему-то ошибся на 3 элементе )
Первый вариант отработал точно.
Потребление памяти одинакого.

 

Powered by ExBB FM 1.0 RC1