2016-11-11 48 views
0

现在,下面的代码对html文档执行测试,看看是否有h1或h2标签包含字符串$ title。代码完美无瑕。

$s1='random text'; 
    $a1='random anchor text'; 
    $href1='http://www.someurl.com'; 
    $document = new DOMDocument(); 
    $libxml_previous_state = libxml_use_internal_errors(true); 
    $document->loadHTML($str); 
    libxml_use_internal_errors($libxml_previous_state); 

    $tags = array ('h1', 'h2'); 
    $texts = array(); 
    foreach($tags as $tag) 
    { 
     $elementList = $document->getElementsByTagName($tag); 
     foreach($elementList as $element) 
     { 
      $texts[$element->tagName] = strtolower($element->textContent); 
     } 
    } 

    if(in_array(strtolower($title),$texts)) { 
     echo '<div class="success"><i class="fa fa-check-square-o" style="color:green"></i> This article used the correct title tag.</div>'; 
    } else { 
     echo '<div class="error"><i class="fa fa-times-circle-o" style="color:red"></i> This article did not use the correct title tag.</div>'; 
    } 

我需要运行三个测试,首先我需要扫描的$ s1的存在的文件,但不知道这一点。通过工作代码,它正在寻找h1或h2标签内的完全匹配。然而,对于$ s1我不寻找完全匹配,只是在任何文本存在的地方 - 无论是否包含其他文本。

然后,我需要另一个精确匹配测试来查找“a”文本中的$ a1,并且还需要测试href是否存在$ href1。

我不知道如何做这些测试。我相信我可以将$ a1测试看作是另一个精确匹配,但不知道如何执行href测试,也不能扫描可能被其他文本包围的字符串。

希望这一切都有道理。

更新

我需要一个解决方案,让我回显一个单一“是字符串是否存在”或“不,它不需要”。类似于当前测试回声的唯一方式,而不是每个回路。我需要每次测试都做一次。

示例结果会是什么样子:

yes $s1 is in the document 
no $s1 is not in the document 
yes $href1 is an href in the document 
no $href1 is not an href in the document 
yes $a1 is an anchor text in the document 
no $a1 is not an anchor text in the document 

我也相信我应该使用SUBSTR(),但我不知道究竟如何。

希望得到一些工作实例和详细解释。

+0

一些提示:1,你可以用'的foreach($文档 - >的getElementsByTagName( '*')为$元素) {'选择所有元素,然后检查'$ element-> textContent'作为你的字符串。 2-请查看[此链接](http://www.the-art-of-web.com/php/html-xpath-query/)**第2步**,以了解如何寻找你的''标记... – EhsanT

+0

不会在第一个提示中,它只会返回,如果它完全匹配。我的意思是,如果一个元素的内容是“随机字符串和单词,然后$ s1和更多的字符和单词” – Bruce

+0

所以在这种情况下,你可以使用正则表达式来匹配你的字符串 – EhsanT

回答

1

下面是从所有文本节点中提取(1)锚点href(2)锚文本(3)h1文本(4)h2文本(5)文本片段并将它们存储在数组中的代码。稍后,它将通过这些数组搜索相同的精确/部分匹配。

我们是用xquery做的,因为使用它从叶节点中提取文本似乎更容易。

代码:

<?php 
    /* returns true if an exact match for $str is found in items of $arr array */ 
    function find_exact($str, array $arr) { 
     foreach ($arr as $i) {if (!strcasecmp($i,$str)) {return(true);}} 
     return(false); 
    } 

    /* returns true if a partial/exact match for $str is found in items of $arr array */ 
    function find_within($str, array $arr) { 
     foreach ($arr as $i) {if (stripos($i,$str)!==false) {return(true);}} 
     return(false); 
    } 

    $s1='random text'; 
    $a1='random anchor text'; 
    $href1='http://www.someurl.com'; 
    $document = new DOMDocument(); 
    $libxml_previous_state = libxml_use_internal_errors(true); 

    /* Sample document. Just for testing */ 
    $str=<<<END_OF_DOC 
<h1>abc h1title def</h1> 
<h2>h2title</h2> 
<div>some random text here</div> 
<div>two</div>three 
<a href='http://www.someurl.com'>some random anchor text here</a> 
<span>four</span>five<span>six<b>boldscript</b></span> 
END_OF_DOC; 

    $document->loadHTML($str); 
    libxml_use_internal_errors($libxml_previous_state); 

    /* We extract the texts into these arrays, for matching later */ 
    $a_texts=array(); $a_hrefs=array(); $h1_texts=array(); $h2_texts=array(); $all_texts=array(); 

    /* We use XPath because it seems easier for extracting text nodes */ 
    $xp = new DOMXPath($document); $eList=$xp->query("//node()"); 
    foreach ($eList as $e) { 
     //print "Node {".$e->nodeName."} {".$e->nodeType."} {".$e->nodeValue."} {".$e->textContent."}<br/>"; 
     if (!strcasecmp($e->nodeName,"a")) { array_push($a_texts,$e->textContent);array_push($a_hrefs,$e->getAttribute("href")); } 
     if (!strcasecmp($e->nodeName,"h1")) {array_push($h1_texts,$e->textContent);} 
     if (!strcasecmp($e->nodeName,"h2")) {array_push($h2_texts,$e->textContent);} 
     if ($e->nodeType === XML_TEXT_NODE) {array_push($all_texts,$e->textContent);} 
    } 

    //var_dump($a_texts); print("<br/>"); var_dump($a_hrefs); print("<br/>"); var_dump($h1_texts); print("<br/>"); 
    //var_dump($h2_texts);print("<br/>");var_dump($all_texts);print("<br/>"); 

    if (find_within($s1,$all_texts)) { print "yes $s1 is in the document<br/>"; } 
    else { print "no $s1 is not in the document<br/>"; } 

    if (find_exact($href1,$a_hrefs)) { print "yes $href1 is an href in the document<br/>"; } 
    else { print "no $href1 is not an href in the document<br/>"; } 

    if (find_within($a1,$a_texts)) { print "yes $a1 is an anchor text in the document<br/>"; } 
    else { print "no $a1 is not an anchor text in the document<br/>"; } 
?> 

结果:

yes random text is in the document 
yes http://www.someurl.com is an href in the document 
yes random anchor text is an anchor text in the document 
+0

与此问题,是我没有办法回声“找不到匹配”。例如,如果我尝试在href中回显“找不到匹配项”......它将在整个文档中为每个href回显“找不到匹配项” - 而不仅仅是一次。 – Bruce

+0

@Bruce,查看修改后的代码。我试图将它与现有的代码集成,将文本提取到数组中,以便我们不需要反复查看(从而避免回声“找不到”太多次)。 – blackpen

+0

你这么多我一直坚持这一个星期。必须在离开时自己创建find_exact函数,但很简单。 :)现在它的工作完美:) – Bruce