PHP:爆炸CSS选择器并与列表进行比较

时间:2017-07-05 12:06:47

标签: php dom simple-html-dom

我有一个Simple HTML DOM的对象,我可以用来收集一些信息。

要获取我可以使用的元素的标记:

$element->parent()->tag();

结果是spandiv等字符串。

获取我正在使用的属性

$element->parent()->getAllAttributes();

可能的结果是

["id"]=> string(4) "huhu" ["class"]=> string(5) "heyho"

或只是

["id"]=> string(4) "huhu"

另一方面,我得到了一个包含以下元素的数组:

array(11) { [0]=> string(2) "em" [1]=> string(5) "style" [2]=> string(1) "a" [3]=> string(3) "img" [4]=> string(4) "code" [5]=> string(3) "pre" [6]=> string(15) "span.helloworld" [7]=> string(2) "h1" [8]=> string(2) "h2" [9]=> string(2) "h3" [10]=> string(6) "button" } array(11) { [0]=> string(2) "em" [1]=> string(5) "style" [2]=> string(1) "a" [3]=> string(3) "img" [4]=> string(4) "code" [5]=> string(3) "pre" [6]=> string(15) "span.helloworld" [7]=> string(2) "h1" [8]=> string(2) "h2" [9]=> string(2) "h3" [10]=> string(6) "button" } array(11) { [0]=> string(2) "em" [1]=> string(5) "style" [2]=> string(1) "a" [3]=> string(3) "img" [4]=> string(4) "code" [5]=> string(3) "pre" [6]=> string(15) "span.helloworld" [7]=> string(2) "h1" [8]=> string(2) "h2" [9]=> string(2) "h3" [10]=> string(6) "button" } array(11) { [0]=> string(2) "em" [1]=> string(5) "style" [2]=> string(1) "a" [3]=> string(3) "img" [4]=> string(4) "code" [5]=> string(3) "pre" [6]=> string(15) "span.helloworld" [7]=> string(2) "h1" [8]=> string(2) "h2" [9]=> string(2) "h3" [10]=> string(6) "button" } array(11) { [0]=> string(2) "em" [1]=> string(5) "style" [2]=> string(1) "a" [3]=> string(3) "img" [4]=> string(4) "code" [5]=> string(3) "pre" [6]=> string(15) "span.helloworld" [7]=> string(2) "h1" [8]=> string(2) "h2" [9]=> string(2) "h3" [10]=> string(6) "button" } array(11) { [0]=> string(2) "em" [1]=> string(5) "style" [2]=> string(1) "a" [3]=> string(3) "img" [4]=> string(4) "code" [5]=> string(3) "pre" [6]=> string(15) "span.helloworld" [7]=> string(2) "h1" [8]=> string(2) "h2" [9]=> string(2) "h3" [10]=> string(6) "button" } array(11) { [0]=> string(2) "em" [1]=> string(5) "style" [2]=> string(1) "a" [3]=> string(3) "img" [4]=> string(4) "code" [5]=> string(3) "pre" [6]=> string(15) "span.helloworld" [7]=> string(2) "h1" [8]=> string(2) "h2" [9]=> string(2) "h3" [10]=> string(6) "button" } array(11) { [0]=> string(2) "em" [1]=> string(5) "style" [2]=> string(1) "a" [3]=> string(3) "img" [4]=> string(4) "code" [5]=> string(3) "pre" [6]=> string(15) "span.helloworld" [7]=> string(2) "h1" [8]=> string(2) "h2" [9]=> string(2) "h3" [10]=> string(6) "button" } array(11) { [0]=> string(2) "em" [1]=> string(5) "style" [2]=> string(1) "a" [3]=> string(3) "img" [4]=> string(4) "code" [5]=> string(3) "pre" [6]=> string(15) "span.helloworld" [7]=> string(2) "h1" [8]=> string(2) "h2" [9]=> string(2) "h3" [10]=> string(6) "button" }

现在我想做一些事情,只有当标签(以及,如果给定,属性)匹配时。

首先很容易:

if ( in_array( $element->parent()->tag, $excludedParents ) { ... }

第二件事是问题,因为我必须拆分span.helloworld并比较tagattributes

接下来的事情是:它应该可以与其他类似css的选择器一样(就像span#id)。

为您提供完整的示例:

html内容如下所示:

<article class="uk-article uk-text-center">
    <p><span class="helloworld">Lorem ipsum dolor</span> sit amet <span id="huhu" class="heyho">consectetur
</article>

现在我循环遍历所有文字元素:

    foreach ( $dom->find( 'text' ) as $element ) {      
        if ( !in_array( $element->parent()->tag, $excluded ) ) {    
                $element->innertext = "test";
        }
    }

    return $dom->save();

好的。我们来看看$excluded

dump($excluded);

array:12 [▼
  0 => "em"
  1 => "style"
  2 => "a"
  3 => "img"
  4 => "code"
  5 => "pre"
  6 => "h1"
  7 => "h2"
  8 => "h3"
  9 => "button"
  10 => "ul"
  11 => "span.helloworld"
]

现在不幸的是,测试if ( !in_array( $element->parent()->tag, $excluded ) )仅适用于真实标签。但不是像span.helloworld那样的“jQuery-like”选择器。

问题是:class / id / other属性以这种方式保存:

dump($element->parent()->getAllAttributes());

array:1 [▼
  "class" => "uk-article uk-text-center"
]

array:1 [▼
  "class" => "helloworld"
]

array:2 [▼
  "id" => "huhu"
  "class" => "heyho"
]

这告诉我,我必须“拆分”选择器并检查它是否是类选择器,id-selector,....

知道如何解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

我想我明白你的意思了。你必须上升2并检查孩子是否匹配css。类似的东西:

foreach ( $dom->find( 'text' ) as $element ) {      
  foreach($excluded as $css){
    foreach($element->parent->parent->find("> $css") as $parent){ // check children of gp
      if($parent == $element->parent) continue(3);
    }
  }
  if ( !in_array( $element->parent()->tag, $excluded ) ) {    
    $element->innertext = "test";
  }
}

不幸的是,我不认为simple-html-dom子选择器(>)是可靠的,因此您可能会遇到一些问题。