PHP:分解CSS选择器并与列表进行比较



我得到了一个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"的选择器上。

问题是:类/id/其他属性以这种方式保存:

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

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

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

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

这告诉我,我必须"拆分"选择器并检查它是否是类选择器、id 选择器......

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

我想我明白你的意思了。你必须上升 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";
}
}

不幸的是,我不认为简单的html-dom子选择器(>)是可靠的,所以你可能会遇到一些问题。

最新更新